MVC 4 client side validation not working

112,785

Solution 1

I had the same problem. It seems that the unobtrusive validation scripts were not loaded (see screenshot at the end). I fixed it by adding at the end of _Layout.cshtml

 @Scripts.Render("~/bundles/jqueryval")

The end result:

   @Scripts.Render("~/bundles/jquery")
   @Scripts.Render("~/bundles/jqueryval")
   @RenderSection("scripts", required: false)

Except for my pretty standard CRUD views everything is Visual studio project template defaults.

Loaded scripts after fixing the problem: enter image description here

Solution 2

Be sure to add this command at the end of every view where you want the validations to be active.

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Solution 3

I finally solved this issue by including the necessary scripts directly in my .cshtml file, in this order:

<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

It's a bit off-topic, but I'm continually amazed by how often this sort of thing happens in Web programming, i.e. everything seems to be in place but some obscure tweak turns out to be necessary to get things going. Flimsy, flimsy, flimsy.

Solution 4

In Global.asax.cs, Application_Start() method add:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyRequiredAttribute), typeof(RequiredAttributeAdapter));

Solution 5

you may have already solved this, but I had some luck by changing the order of the jqueryval item in the BundleConfig with App_Start. The client-side validation would not work even on a fresh out-of-the-box MVC 4 internet solution. So I changed the default:

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));

to

        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.validate*",
                    "~/Scripts/jquery.unobtrusive*"));

and now my client-side validation is working. You just want to make sure the unobtrusive file is at the end (so it's not intrusive, hah :)

Share:
112,785
Javid
Author by

Javid

I am good.

Updated on September 14, 2020

Comments

  • Javid
    Javid over 3 years

    Can anyone tell me why client side validation is not working in my MVC 4 application.

    _layout.schtml

    @Scripts.Render("~/bundles/jquery")
    @RenderSection("scripts", required: false)
    

    In my web.config I have:

    <appSettings>
       <add key="ClientValidationEnabled" value="true" />
       <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    </appSettings>
    

    In my login.cshtml page I have:

    @using (Html.BeginForm())
    {
        <div class="formscontent">
    
            <ol>
                <li>
                    @Html.LabelFor(x => x.AgreementNumber)
                    <br />
                    @Html.TextBoxFor(x => x.AgreementNumber, new { size = "30" })
                    <br />
                    @Html.ValidationMessageFor(m => m.AgreementNumber)
                    <br />
                    <br />
                </li>
                <li>
                    @Html.LabelFor(x => x.UserName)
                    <br />
                    @Html.TextBoxFor(x => x.UserName, new { size = "30" })
                    <br />
                    @Html.ValidationMessageFor(m => m.UserName)
                    <br />
                    <br />
                </li>
                <li>
                    @Html.LabelFor(x => x.Password)
                    <br />
                    @Html.PasswordFor(x => x.Password, new { size = "30" })
                    <br />
                    @Html.ValidationMessageFor(m => m.Password)
                    <br />
                    <br />
                </li>
            </ol>
    
        </div>
        
        <ol>
            <li>
                @Html.CheckBoxFor(m => m.RememberMe)
                @Html.LabelFor(m => m.RememberMe, new { @class = "checkbox" })
            </li>
        </ol>
        
        <br />
        
        <input class="mainbutton" type="submit" value="@Model.Localisation.TranslateHtmlString("LogonBtn")" /><br />
        <div style="text-align: left; padding: 0 5px 5px 10px;">
            Forgot login-info? clik <a class="link" href="@Url.Action("Index", "Credentials")">here.</a>
        </div>
        
    }
    

    In the bottom of login page:

    @section Scripts {
      @Scripts.Render("~/bundles/jqueryval")
    }
    

    JavaScript is enabled in my browser. In the MVC 4 template project from Visual Studio client validation works fine.

    Running the application, on login page when viewing page source, I see this rendered:

    <label for="AgreementNumber">number</label>
    <br />
    <input id="AgreementNumber" name="AgreementNumber" size="30" type="text" value="387893" />
    <br />
    <span class="field-validation-valid" data-valmsg-for="AgreementNumber" data-valmsg-  replace="true"></span>
    

    and in this in the bottom:

    <script src="/BMWebsite/Scripts/jquery.unobtrusive-ajax.js"></script>
    <script src="/BMWebsite/Scripts/jquery.validate.inline.js"></script>
    <script src="/BMWebsite/Scripts/jquery.validate.js"></script>
    <script src="/BMWebsite/Scripts/jquery.validate.unobtrusive.js"></script>
    

    My model properties are annotated:

    public class LogonModel : ModelBase
    {
        [MyRequired("AgreementNumberRequiredProperty")]
        [MyDisplay("AgreementNumberLabel")]
        public string AgreementNumber { get; set; }
    
        [MyRequired("UserNameRequiredProperty")]
        [MyDisplay("UserNameLabel")]
        public string UserName { get; set; }
    
        [MyRequired("PasswordRequiredProperty")]
        [DataType(DataType.Password)]
        [MyDisplay("PasswordLabel")]
        public string Password { get; set; }
    
        [MyDisplay("RememberMeCheckBox")]
        public bool RememberMe { get; set; }
    }
    

    MyRequired is a class derived from the regular RequiredAttribute. The reason is that my error messages are localised by overriding the FormatErrorMessage(string name) method of the RequiredAttribute class. And it works fine - My labels and error messages are localized.

    MyRequired.cs

    public class MyRequiredAttribute : RequiredAttribute
    {
        private readonly string _errorMessagekey;
    
        public MyRequiredAttribute(string errorMessage)
        {
            _errorMessagekey = errorMessage;
        }
    
        public override string FormatErrorMessage(string name)
        {
            var translation = HttpContext.Current.Session["translation"] as LocalisationHelper;
    
            return translation != null ? translation.Translate(_errorMessagekey) : ErrorMessage;
        }
    }
    

    I put a breakpoint in the POST version of my login action method, and it is being hit. The form is posted to server where server side validation happens. Client side validation doesn't happen.

    What am I missing?

    Thank you.

  • Bennor McCarthy
    Bennor McCarthy about 11 years
    Right there in the first line: @Scripts.Render("~/bundles/jquery"), but still worth checking that jquery is actually in the rendered source of the page.
  • Javid
    Javid about 11 years
    I am NOT using the regular html form tag. My form is rendered using the Html.BegingForm() helper.
  • Javid
    Javid about 11 years
    I have set this DataAnnotation attribute on my model properties. I have a class derived from RequiredAttribute
  • Javid
    Javid about 11 years
    I have edited my question providing more information on this.
  • Javid
    Javid about 11 years
    I removed MyRequiredAttribute annotation from the model properties and used the standard RequiredAttribute to annotate my model properties and it worked (client side validation worked). When I used MyRequiredAttribute this attribute was not rendered in the <input> tag: data-val-required="The Agreement number field is required.". But I need my error messages localized. How to fix?
  • Dr Blowhard
    Dr Blowhard about 11 years
    this is a different question - ask it in a new question
  • RJ Cuthbertson
    RJ Cuthbertson over 8 years
    This was what I was missing when using a custom attribute. Thank you.
  • Maximus
    Maximus about 8 years
    I have partial view and I need to paste it directly to view, references in layout does not seem to be working.
  • JDandChips
    JDandChips almost 8 years
    very good shout old boy. I had bundled all of my scripts together and the natural ordering placed the unobtrusive bits above the jqueryval
  • Suhail Mumtaz Awan
    Suhail Mumtaz Awan almost 8 years
    Bundle render scripts in alphabetical order.
  • Deise Vicentin
    Deise Vicentin over 7 years
    I also have partial views. Needed to reference directly in the view to get this working.
  • Jorr.it
    Jorr.it over 6 years
    This solution is needed when form is loaded using ajax
  • Dezzamondo
    Dezzamondo about 4 years
    7 years on and it's still not in the boilerplate _Layout.cshtml file! Timeless advice Liviu!
  • Hasan Shouman
    Hasan Shouman over 2 years
    This also, worked for me, I added this to the web.config in the view folder