Client validation not showing message

18,656

Solution 1

Moving the ValidationSummary inside the form will fix it.

<h2>Create New Account</h2>
<fieldset>
    <legend></legend>
     @using (Html.BeginForm("CreateUser",null)){
        @Html.ValidationSummary()
        @Html.AntiForgeryToken()
        <table class="create">
            <tr>
                <td colspan="2"><b>New Account</b>
            </tr>
            <tr>
                <td>@Html.DisplayNameFor(model=>model.UserName)</td>    <td>@Html.TextBoxFor(model=>model.UserName)</td>
            <td>@Html.DisplayNameFor(model=>model.EmailAddress)</td><td>@Html.TextBoxFor(model=>model.EmailAddress)</td>
            <td><input type="submit" value="Create User" /></td>
        </tr>
    </table>
}
</fieldset>

Solution 2

For anyone stumbling across this who does not wish to be restricted to moving the @Html.ValidationSummary into the form, i.e. it lives in _Layout.cshtml, and you like it there, here's a way around that.

The below method is apparently what is used by Microsoft to populate @Html.ValidationSummary. In it's standard form, it looks for data-valmsg-summary-true in $('this'). this in this case is the calling form. Well, my @Html.ValidationSummary lives in the pageBody <div> on _Layout.cshtml to keep it DRY.

function onErrors(event, validator) { // '#pageBody' is the containing element
    var container = $('#pageBody').find("[data-valmsg-summary=true]"), 
    list = container.find("ul"); if (list && list.length && validator.errorList.length) {
        list.empty(); container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
        $.each(validator.errorList, function () {
             $("<li />").html(this.message).appendTo(list);
        });
    }
}

So far, I've only changed this:

var container = $('this').find("[data-valmsg-summary=true]")

to this:

var container = $('#pageBody').find("[data-valmsg-summary=true]")

Now, I trigger my validation from a button click. To get onErrors(event, validator) to fire, I used the following jQuery:

    $('#btnSave').click(function () {
        if ($('form').valid()) {
           // Do stuff
        } else {
            onErrors(event, $('form').data('validator'));
        }
    });

Voila, @Html.ValidationSummary populates even when using jQuery.unobtrusive.

A big thanks to Leniel Macaferi for pointing me in the right direction here: http://www.leniel.net/2013/08/customizing-aspnet-mvc-html-validation-summary-with-bootstrap-3-panel.html#sthash.jGRguVuV.qSjYUlhS.dpbs

Share:
18,656
Lotok
Author by

Lotok

.NET Developer since 2005

Updated on June 30, 2022

Comments

  • Lotok
    Lotok almost 2 years

    I have a MVC4 internet application with a form for creating user accounts. The form validation works but while the input fails validation no error message is displayed. It still prevents submitting until the validation problem is solved but there is no text

    Razor View Form

    <h2>Create New Account</h2>
    <fieldset>
        <legend></legend>
        @using (Html.BeginForm("CreateUser",null)){
            @Html.AntiForgeryToken()
            <table class="create">
                <tr>
                    <td colspan="2"><b>New Account</b>
                </tr>
                <tr>
                    <td>@Html.DisplayNameFor(model=>model.UserName)</td><td>@Html.TextBoxFor(model=>model.UserName)</td>
                    <td>@Html.DisplayNameFor(model=>model.EmailAddress)</td><td>@Html.TextBoxFor(model=>model.EmailAddress)</td>
                    <td><input type="submit" value="Create User" /></td>
                </tr>
            </table>
        }
    </fieldset>
        @Html.ValidationSummary()
    

    The bundles used include the validation files

    bundles.Add(new ScriptBundle("~/bundles/asset").Include(
                "~/Scripts/jquery-{version}.js",
                "~/Scripts/jquery-ui-{version}.js",
                "~/Scripts/jquery.validate*",
                "~/Scripts/jquery.unobtrusive*"));
    

    The Model used is an entity model, I have added a partial class to annotate the validation requirements

    [MetadataType(typeof(UserProfileMetadata))]
    public partial class UserProfile
    {
        //Empty Class just required for adding class level attribute
    }
    
    public class UserProfileMetadata
    {
        //Fields from user profile requiring annotations
        [EmailAddress]
        [Required]
        [Display(Name = "Email Address")]
        public string  EmailAddress { get; set; }
    
        [Required]
        public string UserName { get; set; }
    
    }
    

    The validation working but now showing the message makes me think it must be a markup error but I just can't see it.