ASP.NET MVC 4 - Clientside Validation Not Working

12,390

I'm wondering what would happen if you altered nevervalid.js so that the code executes before the document is ready.

My basic thinking is that the unobtrusive validation works by parsing the document when the dom is ready... but if you're loading your custom validation stuff at the same time / afterwards, it's not going to know what to do when it comes accross you custom validation data- attribute.

Anyway, try changing nevervalid.js to simply be:

(function($) {
    $.validator.addMethod("nevervalid", function () {
        return false;
    }, "Clientside Should Not Postback");

    $.validator.unobtrusive.adapters.addBool("nevervalid");
})(jQuery);
Share:
12,390
G2Mula
Author by

G2Mula

where grass has grown, grass will always grow - Akokhan

Updated on June 25, 2022

Comments

  • G2Mula
    G2Mula almost 2 years

    I am using Visual Studio 2012 and I cannot get a custom attribute client side logic to work to reproduce at a smaller scale, I created a new MVC 4 project I created the following model and Attribute that will never validate

    public class MyModel
    {
        public int Id { get; set; }
        [Required]
        public string LastName { get; set; }
        [NeverValid(ErrorMessage="Serverside Will Never Validate")]
        public string FirstName { get; set; }
    }
    
    public class NeverValidAttribute : ValidationAttribute, IClientValidatable
    {
        public override bool IsValid(object value)
        {
            return false;
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName });
        }
    
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationRule
            {
                ErrorMessage = this.ErrorMessage,
                ValidationType = "nevervalid"
            };
        }
    }
    

    I then have the following actions added to the HomeController

    public ActionResult Index()
    {
        return View(new MyModel());
    }
    
    [HttpPost]
    public ActionResult Index(MyModel model)
    {
        if (!ModelState.IsValid)
        {
            // Will Always Be Invalid
        }
    
        return View(model);
    }
    

    There is also a javascript file called nevervalid.js

    $(function () {
        $.validator.addMethod("nevervalid", function () {
            return false;
        }, "Clientside Should Not Postback");
    
        $.validator.unobtrusive.adapters.addBool("nevervalid");
    });
    

    and the Index View

    @model CustomAttribute.Models.MyModel
    
    @{
        ViewBag.Title = "Home Page";
    }
    
    @using (Html.BeginForm())
    {
        @Html.ValidationSummary(true)
    
        <fieldset>
            <legend>MyModel</legend>
    
            @Html.HiddenFor(model => model.Id)
    
            <div class="editor-label">
                @Html.LabelFor(model => model.LastName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.LastName)
                @Html.ValidationMessageFor(model => model.LastName)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.FirstName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.FirstName)
                @Html.ValidationMessageFor(model => model.FirstName)
            </div>
    
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>
    }
    
    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
        @Scripts.Render("~/Scripts/nevervalid.js")
    }
    

    The relevant areas in my web.config look like this

    <appSettings>
        <add key="webpages:Version" value="2.0.0.0" />
        <add key="webpages:Enabled" value="false" />
        <add key="PreserveLoginUrl" value="true" />
        <add key="ClientValidationEnabled" value="true" />
        <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    </appSettings>
    

    when the page loads, the following files are loaded (got this from network tab under chrome's F12)

    http://localhost:7440/
    http://localhost:7440/Content/site.css
    http://localhost:7440/Scripts/modernizr-2.5.3.js
    http://localhost:7440/Scripts/jquery-1.7.1.js
    http://localhost:7440/Scripts/jquery.unobtrusive-ajax.js
    http://localhost:7440/Scripts/jquery.validate.js
    http://localhost:7440/Scripts/jquery.validate.unobtrusive.js
    http://localhost:7440/Scripts/nevervalid.js
    

    and my custom attribute adds relevant looking data- stuff to the first name input like so...

        <input class="text-box single-line valid" data-val="true" data-val-nevervalid="Serverside Will Never Validate" id="FirstName" name="FirstName" type="text" value="">
    

    so, I ask you, why oh why does this thing have to postback to do serverside validation while I have some perfectly looking javascript code here? do I have to sacrifice some animal on a moonless night on top of a hill somewhere?

    • Patrick Magee
      Patrick Magee about 11 years
      Does this help, it seems you're not overriding all the required functions in your validation attribute. stackoverflow.com/questions/8284207/…
    • G2Mula
      G2Mula about 11 years
      Hi, Patrick, thanks for taking your time to look at the problem, In my rush to get the smallest reproducable code, I overlooked the second IsValid override... still it does not work... I think I must've gone through all the related SO questions. but nothing... I'm hoping that someone may be able to reproduce it on their end of the world, confirm I aint going insane...
  • G2Mula
    G2Mula about 11 years
    yea, still works and the edit does look much more less "naked", been using jQuery for too long and there are some stuff in it I forgot to ask what they actually mean...
  • Charlino
    Charlino about 11 years
    All good, glad it fixed you problem. The edit was just a best practice thing :-)
  • Seyed Morteza Mousavi
    Seyed Morteza Mousavi over 10 years
    Can anyone help me what is difference between (function($){})(jQuery) and $(document).ready(function{})??
  • G2Mula
    G2Mula over 10 years
    $(document).ready(function{}) gets called when the document is ready (everything has loaded dome is ready blah blah...) (function($){})(jQuery) will be fired immediately it is encountered, it is basically just function($){} called immediately with jQuery as the parameter... hope it makes sense
  • Dilip Langhanoja
    Dilip Langhanoja over 10 years
    Thanks a lot @Charlino after many struggle your answer is very useful to me. I wish I can give you more votes for your answer.
  • Box Very
    Box Very over 3 years
    Thanks for that, that's very helpful, I didn't pay much attention on that subtle part. However, this subtle part change the whole picture. :-)