检查是否为特定表单字段有效

时间:2013-01-14 17:11:03

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

我一直在寻找一段时间,但尚未找到解决方案。

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

无论如何,我的问题是我正在使用Twitter Bootstrap,如果底层字段无效,我需要在error上添加div 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在我的代码段的第一个error插入div课程。

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

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

4 个答案:

答案 0 :(得分: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>

答案 1 :(得分:5)

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

希望它可以帮到你!

答案 2 :(得分:1)

你也可以检查是否有验证信息,快速又脏...

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

答案 3 :(得分:1)

您需要在视图的IsValidField属性中查询ModelStateDictionary的{​​{1}}方法。

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

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

要获取模型属性的字段名称,请使用ViewData API。

Html.NameFor(...)

让我们更进一步,使用实用程序方法扩展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);            
        }
    }
}