MVC4 Razor显示必填字段

时间:2012-08-10 09:10:01

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

在具有默认表单验证的表单中,我有以下代码:

代码:

<div class="item">
    @Html.LabelFor(m => m.Contact.LastName, new { @class="l" } )
    <div class="input">@Html.EditorFor(m => m.Contact.LastName, new { @class="i" })</div>
    <div class="marker">@Html.ValidationMessageFor(model => model.Contact.LastName)</div>
    <div class="clear"></div>
</div>

输出:

<div class="item">
  <label class="l" for="Contact_LastName">Lastname</label>
  <div class="input">
    <input class="i" data-val="true" data-val-length="Required" data-val-length-max="70" data-val-length-min="2" data-val-required="Required" id="Contact_LastName" name="Contact.LastName" type="text" value="" />
  </div>
  <div class="marker">
    <span class="field-validation-valid" data-valmsg-for="Contact.LastName" data-valmsg-replace="true">
    </span>
  </div>
  <div class="clear"></div>
</div>

问题:

现在我想在de marker中显示“*”(星号),当字段出现错误(然后显示错误消息)时它应该消失,或者当字段正确填充时它应该消失。

情况:

所以状态1 - 姓氏:[.....] *

状态2(点击提交后) - 姓氏:[.....] 必需

状态3(有效输入) - 姓氏:[doe ..]

实现这一目标的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

我已经在ValidateMessageFor类(MVC4)中创建了一个重载:

    public  static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, bool addRequiredFieldMark)
    {
        return ValidationMessageFor(htmlHelper, expression, null /* validationMessage */, new RouteValueDictionary(), addRequiredFieldMark: addRequiredFieldMark);
    }

    public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage, IDictionary<string, object> htmlAttributes, bool? addRequiredFieldMark=false)
    {
        return ValidationMessageHelper(htmlHelper,
                                       ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
                                       ExpressionHelper.GetExpressionText(expression),
                                       validationMessage,
                                       htmlAttributes,
                                       addRequiredFieldMark:addRequiredFieldMark);
    }

    private static MvcHtmlString ValidationMessageHelper(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, string validationMessage, IDictionary<string, object> htmlAttributes, bool? addRequiredFieldMark = false)
    {
        string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);

        //Changed (http://stackoverflow.com/questions/8380988/how-to-customize-html-validationmessagefor-in-asp-mvc).
        //FormContext formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();
        FormContext formContext = htmlHelper.ViewContext.ClientValidationEnabled ? htmlHelper.ViewContext.FormContext : null;

        if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName) && formContext == null)
        {
            return null;
        }

        ModelState modelState = htmlHelper.ViewData.ModelState[modelName];
        ModelErrorCollection modelErrors = (modelState == null) ? null : modelState.Errors;
        ModelError modelError = (((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors.FirstOrDefault(m => !String.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0]);

        if (modelError == null && formContext == null)
        {
            return null;
        }

        TagBuilder builder = new TagBuilder("span");
        builder.MergeAttributes(htmlAttributes);
        builder.AddCssClass((modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName);

        if (!String.IsNullOrEmpty(validationMessage))
        {
            builder.SetInnerText(validationMessage);
        }
        else if (modelError != null)
        {
            builder.SetInnerText(GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, modelState));
        }

        if (formContext != null)
        {
            bool replaceValidationMessageContents = String.IsNullOrEmpty(validationMessage);

            // Addition
            if (modelMetadata != null && modelMetadata.IsRequired && addRequiredFieldMark.HasValue && addRequiredFieldMark.Value)
                builder.SetInnerText("*");

            if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
            {
                builder.MergeAttribute("data-valmsg-for", modelName);
                builder.MergeAttribute("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant());
            }
            else
            {
                FieldValidationMetadata fieldMetadata = ApplyFieldValidationMetadata(htmlHelper, modelMetadata, modelName);
                // rules will already have been written to the metadata object
                fieldMetadata.ReplaceValidationMessageContents = replaceValidationMessageContents; // only replace contents if no explicit message was specified

                // client validation always requires an ID
                builder.GenerateId(modelName + "_validationMessage");
                fieldMetadata.ValidationMessageId = builder.Attributes["id"];
            }
        }
        return MvcHtmlString.Create(builder.ToString(TagRenderMode.Normal));
    }

所以这是补充:

if (modelMetadata != null && modelMetadata.IsRequired && addRequiredFieldMark.HasValue && addRequiredFieldMark.Value)                 
builder.SetInnerText("*");

这个剃刀/ cshtml代码:

<div class="item">
    @Html.LabelFor(m => m.Contact.LastName, new { @class="l" } )
    <div class="input">@Html.EditorFor(m => m.Contact.LastName, new { @class="i" })</div>
    <div class="marker">@Html.ValidationMessageFor(model => model.Contact.LastName,true)</div>
    <div class="clear"></div>
</div>

(请注意真正的关键字)