【问题标题】:Check is a specific form field is valid检查特定表单字段是否有效
【发布时间】:2013-01-14 17:11:03
【问题描述】:

我已经找了一段时间了,还没有找到解决办法。

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

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

到目前为止,我有这个:

    <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 在我的 sn-p 的第一个 div 中插入 error 类。

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

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

【问题讨论】:

    标签: c# asp.net-mvc razor validation


    【解决方案1】:

    像这样:

    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>
    

    【讨论】:

    • 我很久以前就问过这个问题,这是一个小项目,从那时起我就继续前进。您的解决方案看起来不错,只是我现在没有时间测试它,我可能最终会这样做。
    • 谢谢,虽然我只使用了 htmlHelper.ViewContext.ViewData.ModelState.IsValidField(expressionText)
    【解决方案2】:

    除了 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 类具有检索验证信息的好方法,因此通过使用上述方法,您可以通过一些变通方法从中获得更多信息。

    希望对你有帮助!

    【讨论】:

    • 这是关键:你需要在ModelState.IsValidField(...)调用中引用正确的className.fieldName,否则无论验证状态如何,每次都会返回true
    【解决方案3】:

    您也可以只检查是否有验证消息,又快又脏...

    <div class="control-group @(Html.ValidationMessageFor(m => m.Password) != null ? "error" : "")">
    

    【讨论】:

    • 我喜欢这个,if/else 的选项也是如此,如果它可以工作的话!
    【解决方案4】:

    需要在视图的ViewData属性中查询ModelStateDictionaryIsValidField方法。

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

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

    要获取模型属性的字段名称,请使用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>
    

    【讨论】:

      猜你喜欢
      • 2012-06-21
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多