3

我们有一个模型,其属性用 [Required] 装饰,非常适合验证。但是,我们想做的是在视图中用星号(或其他样式)标记这些必填字段,以表示在用户输入任何数据进行验证之前它们是必需的。

我似乎无法找到 MVC 框架中内置的任何东西来允许我这样做,因此想知道是否其他人已经解决了这个问题以及如何解决?

最终,我们要防止的是,如果我们随后从模型属性中删除 [Required],则需要在两个地方更改代码。

非常感谢

4

5 回答 5

4

您可以为此构建自己的 HtmlHelper 扩展:

public static string RequiredMarkFor<TModel, TValue>(this HtmlHelper html, Expression<Func<TModel, TValue>> expression)
{
    if(ModelMetadata.FromLambdaExpression(expression, html.ViewData).IsRequired)
         return "*";
    else
         return string.Empty;
}
于 2010-06-04T14:40:19.470 回答
3

Gregoire 和 Faxanadu 的解决方案的问题是始终显示“*”,当使用正常验证验证字段并且使用“Html.ValidationMessageFor()”时也是如此。

因此,如果您像这样使用 html 扩展名:

@Html.EditorFor(model => model.Email)
@Html.RequiredFieldFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)

如果字段存在验证错误,您将看到重复的*


我做了这个修改后的扩展,基于,它还检查该字段是否经过验证。

private static Type[] RequiredTypes = new Type[] { typeof(CustomRequiredAttribute), typeof(RequiredAttribute) };

/// <summary>
/// Generate a &lt;span class="field-validation-error"&gt;*&lt;&lt; element.
/// 
/// See http://koenluyten.blogspot.com/2011/06/denote-required-fields-in-aspnet-mvc-3.html
/// </summary>
public static MvcHtmlString RequiredFieldFor<TModel, TValue>(this HtmlHelper<TModel> html,
    Expression<Func<TModel, TValue>> expression, string validationMessage = "*")
{
    // Get the metadata for the model
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);

    string fieldName = metadata.PropertyName;

    // Check if the field is required
    bool isRequired = metadata
        .ContainerType.GetProperty(fieldName)
        .GetCustomAttributes(false)
        .Count(m => RequiredTypes.Contains(m.GetType())) > 0;

    // Check if the field is validated
    bool isValidated = html.ViewData.ModelState[fieldName] != null;

    // If the field is required and not validated; generate span with an asterix
    if (isRequired && !isValidated)
    {
        var span = new TagBuilder("span");
        span.AddCssClass("field-validation-error");
        span.SetInnerText(validationMessage);

        return MvcHtmlString.Create(span.ToString(TagRenderMode.Normal));
    }

    return null;
}
于 2012-02-08T13:27:22.170 回答
2

如果您在使用“ModelMetadata.FromLambdaExpression”时收到“无效参数”错误,请确保为 HtmlHelper 指定泛型类型参数。这是 Gregoire 解决方案的修订版:

public static string RequiredMarkFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        if (ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).IsRequired)
            return "*";
        else
            return string.Empty;
    }
于 2010-10-07T15:11:05.707 回答
1

如果您使用的是完整表单模板化帮助程序 EditorFor 和 DisplayFor,您需要自定义您自己的 Object.ascx 版本。

布拉德威尔逊有一篇很棒的博客文章概述了这一点:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html

ModelMetadata 上的 IsRequired 属性会发生什么情况。在 Object.ascx 内部:

<%=propertu.IsRequired ? "*" : ""%>

如果您不使用模板化助手,则必须编写自己的 html 助手。你的观点是什么样的?

于 2010-06-04T14:36:58.130 回答
0

我现在的问题有点老了,但我正在努力使用 jquery 提供一个不引人注目的解决方案。

我的目标是让所有输入都标记有 data-val-required 属性,然后将其标签元素设置为标记为

这是示例 jquery 代码:

$('[data-val-required]').each(function() { 
    var $label = $('label[for=' + this.name + ']');

    //from here we can manipulate the label element
    $label.css('font-weight', 'bold');
    $label.text($label.text() + ' *');
});
于 2012-06-27T14:30:36.687 回答