How to customize Html.ValidationMessageFor in ASP MVC

后端 未结 7 859
Happy的楠姐
Happy的楠姐 2020-12-05 07:46

Is it possible to customize the Html.ValidationMessageFor method so that it produces different HTML?

I want to do something similar to:

相关标签:
7条回答
  • 2020-12-05 07:54

    I used another way:

        public static MvcHtmlString DivValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        {
            return MvcHtmlString.Create(htmlHelper.ValidationMessageFor(expression).ToString().Replace("span", "div"));
        }
    

    This way you can use the built in way, but replace the span with a div.

    If you need any other overloads of the function, just duplicate as necessary.

    0 讨论(0)
  • 2020-12-05 07:54

    Yes, just use a metamodel for the field:

    [MetadataType(typeof(YourMetaData))]
    public partial class YOURCLASS
    {
        [Bind(Exclude = "objID")]
        public class YourMetaData
        {
            [Required(AllowEmptyStrings = false, ErrorMessage = "Please enter a name")]
            public object Name { get; set; }
        }
    }
    

    Change your message at the ErrorMessage field :) Hope this help :)

    0 讨论(0)
  • 2020-12-05 08:02

    Maybe you can put that code

    string propertyName = ExpressionHelper.GetExpressionText(expression);
    string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName));
    
    if (helper.ViewData.ModelState[name] == null ||
        helper.ViewData.ModelState[name].Errors == null ||
        helper.ViewData.ModelState[name].Errors.Count == 0)
        {
            return MvcHtmlString.Empty;
        }
    

    on top of the answered function, so that the div doesn't appear on the form load.

    0 讨论(0)
  • 2020-12-05 08:03

    The only need for change of the default tag generation was in my case, that spans behavior results in anoying margin setups.

    I resolved this by using 'display: block'

    Maybe this helps some people..

    0 讨论(0)
  • 2020-12-05 08:05

    I created ValidationMessageAsStringFor which just returns the error message as string. It is basically a simplified version of ValidationMessageFor:

    public static MvcHtmlString ValidationMessageAsStringFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        var field = ExpressionHelper.GetExpressionText(expression);
        string modelName = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(field);
    
        if (!helper.ViewData.ModelState.ContainsKey(modelName))
        {
            return null;
        }
    
        var modelState = helper.ViewData.ModelState[modelName];
        var modelErrors = (modelState == null) ? null : modelState.Errors;
        var modelError = ((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors.FirstOrDefault(m => !String.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0];
    
        if (modelError == null)
        {
            return null;
        }
    
        var errorMessage = GetUserErrorMessageOrDefault(helper.ViewContext.HttpContext, modelError, modelState);
    
        return MvcHtmlString.Create(errorMessage);
    }
    
    private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState)
    {
        if (!string.IsNullOrEmpty(error.ErrorMessage))
        {
            return error.ErrorMessage;
        }
    
        if (modelState == null)
        {
            return null;
        }
    
        return modelState.Value?.AttemptedValue;
    }
    

    With this in place and after importing the namespace containing the new helper, just create the HTML code you need:

    <div class="field-error-box">
        <div class="top"></div>
        <div class="mid"><p>@Html.ValidationMessageAsStringFor(m => m.FieldName)</p></div>
    </div>
    
    0 讨论(0)
  • 2020-12-05 08:09

    I am not sure if it's possible to use paragraph instead of default span, as it may make impossible for validation plugin to place error messages. But for div -s, thats easy - you could write custom html helper.

    Something along these lines (may need further testing/coding). You will need to include the namespace of this static extension method in your view, or put this into System.Web.Mvc.Html directly.

    public static class Validator
    {
        public static MvcHtmlString MyValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
        {
            TagBuilder containerDivBuilder = new TagBuilder("div");
            containerDivBuilder.AddCssClass("field-error-box");
    
            TagBuilder topDivBuilder = new TagBuilder("div");
            topDivBuilder.AddCssClass("top");
    
            TagBuilder midDivBuilder = new TagBuilder("div");
            midDivBuilder.AddCssClass("mid");
            midDivBuilder.InnerHtml = helper.ValidationMessageFor(expression).ToString();
    
            containerDivBuilder.InnerHtml += topDivBuilder.ToString(TagRenderMode.Normal);
            containerDivBuilder.InnerHtml += midDivBuilder.ToString(TagRenderMode.Normal);
    
            return MvcHtmlString.Create(containerDivBuilder.ToString(TagRenderMode.Normal));
        }
    }
    

    As you see, this uses default ValidationMessageFor method, to not interfere with validation-plugin error message processing.

    And you use this simply, as default validation message helper

    @Html.MyValidationMessageFor(model => model.SomeRequiredField)
    
    0 讨论(0)
提交回复
热议问题