10

我一直在寻找一段时间,但还没有找到解决方案。

我是 ASP.NET 和 MVC4/Razor2 新手,所以我主要在编辑默认项目。

无论如何,我的问题是我正在使用 Twitter Bootstrap,如果底层字段无效,我需要error在 a 上添加一个 CSS 类。div

到目前为止,我有这个:

    <div class="control-group error">
      @Html.LabelFor(m => m.Password, new { @class = "control-label" })
      <div class="controls">
        @Html.PasswordFor(m => m.Password)
        @Html.ValidationMessageFor(m => m.Password, null, new { @class = "inline-help error" })
      </div>
    </div>

当字段无效时,我应该怎么做才能让 Razor在我的代码段error的第一个中插入类。div

更新:我找到了一种方法,但与其他代码相比感觉不对。有没有更好的方法或者是这样做方法?

<div class="control-group@((!ViewData.ModelState.IsValidField("Password")) ? " error" : "")">
4

4 回答 4

9

像这样:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString AddClassIfPropertyInError<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> expression, 
        string errorClassName)
    {
        var expressionText = ExpressionHelper.GetExpressionText(expression);
        var fullHtmlFieldName = htmlHelper.ViewContext.ViewData
            .TemplateInfo.GetFullHtmlFieldName(expressionText);
        var state = htmlHelper.ViewData.ModelState[fullHtmlFieldName];
        if (state == null)
        {
            return MvcHtmlString.Empty;
        }

        if (state.Errors.Count == 0)
        {
            return MvcHtmlString.Empty;
        }

        return new MvcHtmlString(errorClassName);
    }
}

那么在你看来:

<div class="control-group @Html.AddClassIfPropertyInError(x => x.Email, "error")">
    <label class="control-label">Email</label>
    <div class="controls">
        <input type="text" placeholder="Email" name="Email" />
        <span class="help-inline">@Html.ValidationMessageFor(x => x.Email)</span>
    </div>
</div>
于 2013-05-08T19:10:38.380 回答
6

除了 Loki 所说的之外,我还遇到了一个很好且整洁的解决方案,可以使用 ModelState 类并检索特定信息来实现我想要的每个验证逻辑:

假设您要检查模型中名为“InnerClass”和字段“Name”的类的验证:

if (ModelState["InnerClass.Name"].Errors.Count > 0)
{
    foreach (var error in ModelState["InnerClass.Name"].Errors)
    {
        message = error.ErrorMessage;
        isValidFlag = false;
    }
}

除了上述条件,您也可以使用它:

ModelState.IsValidField("InnerClass.Name")

ModelState 类具有检索验证信息的好方法,因此通过使用上述方法,您可以通过一些变通方法从中获得更多信息。

希望对你有帮助!

于 2014-11-17T10:57:39.183 回答
1

您也可以检查是否有验证消息,快速而肮脏......

<div class="control-group @(Html.ValidationMessageFor(m => m.Password) != null ? "error" : "")">
于 2015-10-22T00:27:24.063 回答
1

您需要查询视图的属性中的IsValidField方法。ModelStateDictionaryViewData

对于不属于层次结构的模型,更新中的答案将起作用。

对于属于层次结构的模型,您需要指定与整个模型相关的字段名称。

要获取模型属性的字段名称,请使用Html.NameFor(...)API。

ViewData.ModelState.IsValidField( Html.NameFor(m => m.Password).ToString() )

让我们更进一步,并使用一种实用方法扩展,该方法将在字段无效HtmlHelper时输出文本

namespace System.Web.Mvc.Html
{
    public static class GeneralExtensions
    {
        public static MvcHtmlString TextForInvalidField<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string text)
        {
            if(htmlHelper.ViewData.ModelState.IsValidField(htmlHelper.NameFor(expression).ToString()))
            {
                return MvcHtmlString.Empty;
            }
            return MvcHtmlString.Create(text);            
        }
    }
}

最终结果(来自您的原始示例)将如下所示:

<div class="control-group @Html.TextForInvalidField(m => m.Password, "error")">
  @Html.LabelFor(m => m.Password, new { @class = "control-label" })
  <div class="controls">
    @Html.PasswordFor(m => m.Password)
    @Html.ValidationMessageFor(m => m.Password, null, new { @class = "inline-help error" })
  </div>
</div>
于 2016-11-21T23:38:13.163 回答