Question

In my MVC3 application I have the model ( not important properties deleted ):

public class AccountViewModel
{
    [StringLength(65)]
    public string Property1 { get; set; }

    [StringLength(65)]
    public string Property2 { get; set; }
}

The problem is when an action is submited validation attribute called twice, and I can get 4 errors in summary, instead of 2:

'Property1' length must be less than 65 characters
'Property1' length must be less than 65 characters
'Property2' length must be less than 65 characters
'Property2' length must be less than 65 characters

I dont use Validate method in my controller's code. The problem appears also with my custom attributes, but its not happens with Required attribute. Also I have to note that ctor of the custom attributes also called twice

My action

[HttpPost]
public ActionResult CreateOrEdit(AccountViewModel model) {

    if (!ModelState.IsValid) {
        return View("Edit", model);
    }

    try {
        _accountService.InsertOrUpdate(model);

    }
    catch (Exception ee) {
        ModelState.AddModelError("", ee.Message);
        return View("Edit", model);
    }

    return RedirectToAction("Index");
}

On View I render my errors using:

@{
    var errors = ViewData.ModelState.Errors();
    <div class="alert alert-block alert-error @(errors.Count == 0 ? "hide" : "")" > 
    <h4 class="alert-heading"> You got an error!</h4> 
    <ul>
        @foreach (var error in errors) {
            <li>@error</li>
        }
    </ul>
    </div>
}

And I double re-check once more that ViewData.ModelState already contains errors twice.

Was it helpful?

Solution

The problem was in integrating Ninject. If you use Ninject.MVC package ( I use version 3 ) it registers his own ModelValidationProvider while initializing and removes the old one:

In Ninject.Web.Mvc.MvcModule

this.Kernel.Bind<ModelValidatorProvider>().To<NinjectDataAnnotationsModelValidatorProvider>();

In Ninject.Web.Mvc.NinjectMvcHttpApplicationPlugin:

public void Start()
{
    ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
    DependencyResolver.SetResolver(this.CreateDependencyResolver());
    RemoveDefaultAttributeFilterProvider();
}

So, rather than creating my own implementation of IDependencyResolver ( Ninject Kernel wrapper ) I followed this tutorial or you should remove Ninject.MVC package and remove its binaries from the bin folder.

OTHER TIPS

This issue is caused by improper use of NInject.

To solve this issue In NinjectWebCommon class CreateKernel() method add kernel.Rebind<ModelValidatorProvider>().To<NinjectDefaultModelValidatorProvider>();

Here is the code sample.

private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            try
            {
                kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
                kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
                RegisterServices(kernel);
                GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
                kernel.Rebind<ModelValidatorProvider>().To<NinjectDefaultModelValidatorProvider>();
                return kernel;
            }
            catch
            {
                kernel.Dispose();
                throw;
            }
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top