How to access client-side model errors?

I do not like the built-in Html.ValidationSummary helper because I want a single post to be displayed at the top of my form, for example ...

There are validation errors. Invalid fields are highlighted.

The built-in ValidationSummary either does not display anything or displays a list of all the fields. I just want a short message.

I have a div at the top of my form in the style I want, and then when the page loads, I connect the following method to the form ...

function CheckFormForValidationErrors() { if (!$("form").valid()) { $(".validation-notification").css("visibility", "visible"); } } 

This works great when there are validation errors on the client. The problem is that client-side validation succeeds, but server-side validation, such as the login form. If the user enters the correct username and password, the form check succeeds, but the login fails. On the server side, I am adding a model error, for example ...

 ModelState.AddModelError(string.Empty, "Login failed"); 

But I can’t figure out how to display the message on the client. If you have a better idea to achieve my goal, I’m ready to give up my idea and change course. What I'm trying to do should not be so difficult.

+4
source share
2 answers

You have many options. If you want to display a message, create this:

 ModelState.AddModelError(string.Empty, "Login failed"); 

You just need this in your opinion:

 @Html.ValidationMessage(String.Empty) 

This, however, will wrap the message in <span class="field-validation-error"></span> , but the default styles can easily be overridden if you wish.

However, based on the use case described above, what you think is just a static legend (ish) that explains: "There are validation errors. Invalid fields are highlighted." whenever one or more verification errors appear on the screen.

So how about this:

 namespace MvcApplication.Web.Extensions { public static class HtmlHelperExtensions { private const string ValidationLegendHtml = "<div class=\"validation-legend\">{0}</div>"; private const string DefaultValidationLegend = "There are validation errors. The invalid fields have been highlighted"; public static MvcHtmlString ValidationLegend( this HtmlHelper htmlHelper, string message = DefaultValidationLegend) { if(htmlHelper.ViewData.ModelState.IsValid) { return null; } return new MvcHtmlString(String.Format(ValidationLegendHtml, message)); } } } 

Then in the view you just need to insert:

 @Html.ValidationLegend() //Use the default legend message @Html.ValidationLegend("Something went wrong!") //Specific message 

Then the legend will be displayed if the form is invalid and completely invisible when it is valid!

You will also need to add the namespace of the new extension to Views /web.config (do not confuse with the root web.config) as follows:

 <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <!-- Add Me! --> <add namespace="MvcApplication.Web.Extensions"/> </namespaces> </pages> 

Unfortunately, this will not give you intellisense for the new extension method, if it is important, you can alternatively (or optionally) add a using statement to extend to the top of your view immediately after the @model

 @model MvcApplication.Web.Models.LoginModel @using MvcApplication.Web.Extensions 

EDIT

If you want to support the display of this client side, as well as change the extension to:

 public static MvcHtmlString ValidationLegend( this HtmlHelper htmlHelper, string message = DefaultValidationLegend) { var tagBuilder = new TagBuilder("div"); tagBuilder.SetInnerText(message); tagBuilder.AddCssClass("validation-legend"); if(htmlHelper.ViewData.ModelState.IsValid) { tagBuilder.AddCssClass("hide"); } return new MvcHtmlString(tagBuilder.ToString()); } 

Make sure you have a CSS rule .hide { display: none; } .hide { display: none; } .

EDIT Again

You can leave it until jquery.validate to automatically show / hide the legend by setting the default value for the errorContainer configuration parameter to match the legend CSS class. This can be done by declaring the script as follows:

 <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script type="text/javascript"> jQuery.validator.setDefaults({ errorContainer: '.validation-legend' }); </script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

Notice the setDefaults call that appears after the jquery.validate script tag, but before the jquery.validate.unobtrusive script tag. This order is important. Also note that any validation error will show all .validation-legendends, so if you have screens with two different validation legends, you might need a little more.

+2
source

When you are in your view, ModelState is in ViewData p>

  ViewData.ModelState 

And to receive error messages:

  foreach(string key in ViewData.ModelState.Keys) { foreach (var error in ViewData.ModelState[key].Errors) { string err = error.ErrorMessage; } } 

and in Razor, maybe it will work (my Razor is rusty)

 @if (!ViewData.ModelState.IsValid) { <ul> @foreach (string key in ViewData.ModelState.Keys) { @foreach (var error in ViewData.ModelState[key].Errors) { <li>@error.ErrorMessage</li> } } </ul> } 
+4
source

Source: https://habr.com/ru/post/1394511/


All Articles