Custom ValidationSummary template Asp.net MVC 3

前端 未结 7 2162
耶瑟儿~
耶瑟儿~ 2020-11-30 18:59

I am working on a project with Asp.Net MVC3

In a View I have @Html.ValidationSummary(true) and as usually it produces

相关标签:
7条回答
  • 2020-11-30 19:32

    My approach is to use a custom ValidationSummary.cshtml:

    @model ModelStateDictionary
    
    @if(!Model.IsValid)
    {
        <div class="validation-summary-errors">
            <ul>
                @foreach (var modelError in 
                         Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
                {
                    <li>@modelError.ErrorMessage</li>
                }
            </ul>
        </div>
    }
    

    Put this partial view in your Shared folder and refer to it from your code:

    @Html.Partial("_ValidationSummary", ViewData.ModelState);
    

    This way you remain in full control of your html.

    0 讨论(0)
  • 2020-11-30 19:32

    I wanted to show just top-level message and nothing else. We already have validation next to the fields below. Working off @Leniel-Macaferi's solution this is what I did to make it work with jQuery validation: (added style="display: none;")

    <div class="@(Html.ViewData.ModelState.IsValid ? "validation-summary-valid" : "validation-summary-errors")"
         data-valmsg-summary="true">
        <div>
            There are still some fields not filled in before we can submit this. Please correct.
        </div>
        <div style="display: none;">
            <ul>
                @foreach (var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
                {
                    <li>@modelError.ErrorMessage</li>
                }
            </ul>
        </div>
    </div>
    
    0 讨论(0)
  • 2020-11-30 19:42

    Just posting my answer here because it's working well for me ;)

    I use a simple extension method that takes an MvcHtmlString and decodes it back to HTML:

        public static MvcHtmlString ToMvcHtmlString(this MvcHtmlString htmlString)
        {
            if (htmlString != null)
            {
                return new MvcHtmlString(HttpUtility.HtmlDecode(htmlString.ToString()));
            }
            return null;
        }
    

    To plumb this in, I add the validation summary helper to my chstml like this:

    @Html.ValidationSummary(true).ToMvcHtmlString()
    

    This means, I can add custom HTML to my validation summaries:

    ModelState.AddModelError("", "<p>This message can have html in it</p>");
    

    And I can even add custom HTML to my field validation messages:

    ModelState.AddModelError("MyField", "<p>This message can have html in it</p>");
    

    And to get my field validation messages to work with HTML:

    @Html.ValidationMessageFor(model => model.MyField).ToMvcHtmlString();
    
    0 讨论(0)
  • 2020-11-30 19:45

    I've just had to do something similar for server side validation only ( e.g checking file contents) and have ended up completely usurping the @Html.ValidationSummary altogether with quite a nice little work around.

    We have a BaseController class that extends Controller, and inside we override the OnActionExecuting method for several purposes. We create a new list in ViewBag for our error messages and ensure before any action runs it is initialized. Then we can add our errors to be displayed to it, and display on screen.

    For the purposes of this question it would look like this.

    public class BaseController : Controller
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (ViewBag.ErrorsList == null)
            {
                ViewBag.ErrorsList = new List<string>();
            }
        }
    }
    

    Then in our _Layout.cshtml add the following above your @RenderBody()

    @if(ViewBag.ErrorsList.Count > 0)
    {
        <div class="container margin-top-10 alert alert-danger">
            <h3><i class="glyphicon glyphicon-warning-sign"></i></h3><br/>
            @foreach (string error in @ViewBag.ErrorsList)
            {
                @error <br/>
            }
        </div>
        @RenderBody()
    }
    

    Now whenever an error occurs server side that we want to display as a validation error message we simply add it to our ViewBag.ErrorsList

    ViewBag.ErrorsList.Add("Something bad happened...");
    

    And voila, one custom container for your server side validation error messages with any styles you want on it, with errors passed in the same manner as ValidationSummary.

    0 讨论(0)
  • 2020-11-30 19:48

    Building upon flos's answer, I made it compatible with Microsoft's jQuery Unobtrusive Validation and added Bootstrap's 3 panel styling. Here's the new code:

    @model ModelStateDictionary
    
    <div class="@(Html.ViewData.ModelState.IsValid ? "validation-summary-valid" : "validation-summary-errors") panel panel-danger"
         data-valmsg-summary="true">
        <div class="panel-heading">
            Please, correct the following errors:
        </div>
        <div class="panel-body">
            <ul>
                @foreach(var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
                {
                    <li>@modelError.ErrorMessage</li>
                }
            </ul>
        </div>
    </div>
    

    You can read about it in full detail here:

    Creating a custom ASP.NET MVC @Html.ValidationSummary styled with Bootstrap 3 panel

    I also created a sample ASP.NET MVC project to show this custom ValidationSummary in action. Get it here:

    https://github.com/leniel/AspNetMvcCustomHtmlValidationSummary

    0 讨论(0)
  • 2020-11-30 19:56

    This question details the procedure of writing custom validation summary.

    EDIT This will do what you want:

    public static class LinqExt 
    {
        public static string MyValidationSummary(this HtmlHelper helper, string validationMessage="")
        {
            string retVal = "";
            if (helper.ViewData.ModelState.IsValid)
                return "";
    
            retVal += "<div class='notification-warnings'><span>";
            if (!String.IsNullOrEmpty(validationMessage))
                retVal += helper.Encode(validationMessage);
            retVal += "</span>";
            retVal += "<div class='text'>";
            foreach (var key in helper.ViewData.ModelState.Keys) 
            {
                foreach(var err in helper.ViewData.ModelState[key].Errors)
                    retVal += "<p>" + helper.Encode(err.ErrorMessage) + "</p>";
            }
            retVal += "</div></div>";
            return retVal.ToString();
        }
    }
    

    The code is self explanatory; just enumerating through modelstate errors and wrapping errors in dom element of your choice. There is an error that is if i use it like:

    <%:Html.MyValidationSummary()%>
    

    It will display html tags on the page as text rather than rendering it.

    <%=Html.MyValidationSummary()%>
    

    This works fine.

    0 讨论(0)
提交回复
热议问题