Unobtrusive Validation Keeps breaking in MVC4
Asked Answered
G

4

6

I have been having a wierd issue that is driving me absolutely crazy.

It started with the following error out of the blue after it had been working great:

Validation type names in unobtrusive client validation rules must be unique. The following     
validation type was seen more than once: required

This error first started on one of my controllers in Area/Admin/WebSites. But as soon as my auth cookie expired I got it on my Login page as well on the EditFor(m=>m.UserName) line. I combed through my code looking for duplicate Required attribute anywhere on any model that might be remotely named the same to no avail.

I even went into my LoginViewModel, removed the [Required] From UserName. The error moved to the EditFor(m=>m.Password). I removed the Required from Password as well, and the error moved the RememberMe line but there was no Required attribute on that member at all even. In fact I have nothing else even remotely named RememberMe in any other class anywhere.

Okay, well I gave up and started rebuilding the webSite project from scratch (not the rest of the solution) and still ended up with the same thing.

Out of desperation, I rebuild the entire solution from scratch, only copying the *.cs files in and manually reloading all the references thinking there was a duplicate reference somewhere.

Once I got to the point of building the MVC4 project once again I did it in stages to see if I could figure what was happening. It was doing fine, loading up and I could log in, etc, until I started adding Areas. At first I just copied the Areas folder directly into the project (all the namespace names are the same, so this should have been fine). But sure enough I started getting this error right way.

Okay, so I started deleting controllers in reverse order of my creating them originally. The site never returned to normal until I had deleted the Areas folder completely.

Testing this, as soon as I created an Areas folder in the project, it would break. Same thing if I used the GUI to create the new Area.

Okay, back to the drawing board. Recreated the MVC4 project from scratch, this time outside of the solution and only pulled in the 2 critical NuGet packages critical to my solution at this point: Ninject.MVC3 and Mvc3ControlsKit (the one from nuget which is for both 3 & 4). Okay everything finally starts working great. At this point, my Jquery is version 1.7.2 with the default Jquery UI that comes with MVC4.

At some point, I ran into a problem with the jquery dialog not closing so I installed JQuery 1.8.2 and the latest JQuery UI from NuGet. Everything worked fine until I went to add a completely blank Controller in my Admin Area and this error popped up again.

Okay, back to the drawing board again... I rebuilt it in stages, testing at each point. This time not installing the latest JQuery goodies. Everything starts working fine again. Added a new controller, then two. Okay, made a valid copy of this version and set it aside. Updated Jquery and Jquery UI to latest versions. Add a new controller in the area and it still continues to work to my complete frustration.

My Entities are all using Fluent API to configure my entities with no DataAnnotatian Attributes at all. Any ideas? I keep waiting for it to break again.

EDIT:

Here is some more information I just figured out. The error is occuring on this line of code in my LogIn Partial View. My model is

public class LoginViewModel 
{
    [Required]
    [Display(Name = "User Name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }

    /// <summary>
    /// Role
    /// </summary>
    public string Role { get; set; }

}

The error occurs when calling this line in the view:

@Html.TextBoxFor(m => m.UserName)

At this point, Ninject takes over and immediately after returning from the following method in the Ninject.Web.Mvc.Validation.NinjectDataAnnotationsModelValidatorProvider class, the aforementioned unobtrusive validation error occurs. Additionally, I have confirmed that this method has correctly identified the required validations and injected them. The exception is not occurring in this method but afterwards.

protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        var validators = base.GetValidators(metadata, context, attributes);
        foreach (var modelValidator in validators.OfType<DataAnnotationsModelValidator>())
        {
            var attribute = this.getAttributeMethodInfo.Invoke(modelValidator, new object[0]);
            this.kernel.Inject(attribute);
        }

        return validators;
    }
Gemsbok answered 7/10, 2012 at 15:50 Comment(5)
This can happen if you are including script tags more than once, such as in a partial view. You need to look at the final HTML that is generated and figure out the problem there, then you can track it back to your source.Prebend
@MystereMan Thanks. I am assuming you mean like <script></script> and not just reference the script libraries? I already checked to make sure the libraries were not being ref'd twice. If this happens again, will check on multiple <script></script> elements.Gemsbok
Well, it is happening again now, and all I did was wait until the next day. Didn't add anything. Checked for dupe adding of scripts and nada.Gemsbok
Well, if you have a url we can go to and find the problem that would help, otherwise not much we can do, as this is not a common problem.Prebend
Yeah, I realize that. Unfortunately, I do not have this published yet. I will bet it is something stupid I have done; just frustrating. I have added more info to my question above. I am wondering if Ninject is the culprit. Just grabbing at straws atm.Gemsbok
F
5

The error occurs because you are trying to use a mixed validation solution in your project and two providers are trying to add unobtrusive required validation for a field and hence the duplicate issue fires up.

Make sure that you are not using both dataannotation and fluent validation to perform a same validation over a same property (like required in your case).

Fronia answered 9/10, 2012 at 12:41 Comment(3)
I agree it has to be this, but I am not using Fluent validation directly on my view models, most assuredly not LoginViewModel. I am suspicious it is something internal to Ninject.MVC assembly that causes this double validation.Gemsbok
Well, just to see, I went ahead and uninstalled Ninject and installed and setup Unity.MVC and it is working so far. I will give it some time and keep looking here to see if anyone has a definitive answer re Ninject. Considering my track record on this issue, it will probably break tomorrow.Gemsbok
@Mark saved me tons of time.. +1Scaffolding
P
12

The solution (if Ninject is being used) is to unbind the binding.

kernel.Unbind<ModelValidatorProvider>();

Paleoasiatic answered 30/9, 2013 at 12:36 Comment(1)
Ah that would make sense. Unfortunately, I have been using Unity for a while in my personal projects and this issue has not come up in the company I work for (which does use Ninject still). I will keep that in mind if a similar issue once again. I would imagine that Unity would have a similar function.Gemsbok
F
5

The error occurs because you are trying to use a mixed validation solution in your project and two providers are trying to add unobtrusive required validation for a field and hence the duplicate issue fires up.

Make sure that you are not using both dataannotation and fluent validation to perform a same validation over a same property (like required in your case).

Fronia answered 9/10, 2012 at 12:41 Comment(3)
I agree it has to be this, but I am not using Fluent validation directly on my view models, most assuredly not LoginViewModel. I am suspicious it is something internal to Ninject.MVC assembly that causes this double validation.Gemsbok
Well, just to see, I went ahead and uninstalled Ninject and installed and setup Unity.MVC and it is working so far. I will give it some time and keep looking here to see if anyone has a definitive answer re Ninject. Considering my track record on this issue, it will probably break tomorrow.Gemsbok
@Mark saved me tons of time.. +1Scaffolding
G
2

This is not necessarily a satisfactory answer for everyone on this issue, but I resolved my problem by switching to Unity for my DI. I have determined that, yes, it is because, as Mark said, it is probably due to mixed validation. I am using DataAnnotation in my code; it may be that Ninject is using Fluent Validation internally, but I do not know enough to tell for sure, and don't have the energy to continue on this pursuit since I have found an answer satisfactory to myself.

I like Ninject, but in my case the latest version Unity is actually just as easy to use since all I have to do is add one file (bootstrapper.cs) and call BootStrapper.BuildUnityContainer() from the startup event. So, I will stick with this solution for now.

Gemsbok answered 18/10, 2012 at 0:8 Comment(0)
E
1

I had the same error in an MVC4 project where I was using fluent validation. My mistake was that I used .NotNull() and .NotEmpty(for the same field):

RuleFor(i => i.SomeValue).NotNull().NotEmpty();

Removing the last .NotEmpty() solved the problem.

Enchantress answered 7/10, 2014 at 7:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.