Fabis
Fabis

Reputation: 2062

MVC Unobtrusive validation data-val-* markup attributes not being generated

Edit: It seems as though no attributes work whatsoever, validation or not. For example, [DataType(DataType.Date)] doesn't change the markup in anyway either, while it should add 'type=date' to the element, the [Authorize] attribute lets even unauthorized users through etc. Anywone have any ideas about what could be the problem?

Edit 2: Added the following while trying to figure out what's wrong:

ModelMetadata metadata = ModelMetadata.FromLambdaExpression(m => m.Name, Html.ViewData);
var val = metadata.GetValidators(new ControllerContext());
var attributes = metadata.ContainerType.GetProperties().Where(x => x.Name == "Name").FirstOrDefault().CustomAttributes;

The 'val' variable doesn't return any validators, while in a new project the same line works correctly and returns an IEnumerable of all the attributes the model property has. The 'attributes' variable, though, does find all the attributes the property has. So where do I go from here and find out what's wrong?

Edit 3: So I compared what the property 'ModelValidatorProviders.Providers' returns in Global.asax's 'Application_Start()' method between my project and a new project and it turns out that for some reason for my project it doesn't have a 'DataAnnotationsModelValidatorProvider'. So I did this at 'Application_Start()':

ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());

And now the validation works (except the [Authorize] attribute and others not related to models, it looks like they still dont work)! Not much of a fix, though, is it. Why isn't the provider in the ModelValidatorProviders property in the first place? Could it have anything to do with the fact that I have Autofac installed and maybe that messes with it somehow?

Edit 4: Fixed it, see answer.

Original post:

I'm pulling my hair out at this point, because I've read multiple articles about this and none of them help. The weird part is that the validation worked before and then it suddenly stopped working (I didn't change anything). I even restarted my PC, but that didn't really help.

My ViewModel looks like this (the validation doesn't work anywhere on the site, so I could give you literally any viewmodel):

public class ChangePasswordViewModel
{
    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Current password")]
    public string OldPassword { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "New password")]
    public string NewPassword { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm new password")]
    [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

And here's the view (pretty much the default MVC view as well, so there's nothing wrong with it):

@model AwenterWeb.Models.ChangePasswordViewModel
@{
    ViewBag.Title = "Change Password";
}

<h2>@ViewBag.Title.</h2>

@using (Html.BeginForm("ChangePassword", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Change Password Form</h4>
    <hr />
    @Html.ValidationSummary("", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(m => m.OldPassword, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Change password" class="btn btn-default" />
        </div>
    </div>
}
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

I put a breakpoint on Html.TextBoxFor and made sure that indeed the HTML that it returns does not have the necessary validation attributes. What else could be broken? It is definitely not an issue with the Validation JS files, but rather Html.TextBoxFor and other helper classes for some reason can't tell that the fields have attributes on them!

Upvotes: 2

Views: 1123

Answers (1)

Fabis
Fabis

Reputation: 2062

After a whole day of trying to figure out what could possibly be wrong I decided to completely uninstall any traces of Autofac and Ninject I had (don't know why I had Ninject, don't remember ever installing it) and surprise, surprise things started working again. I then reinstalled the latest versions of the Autofac packages I had and attributes still worked, so maybe it had something to do with those rogue Ninject packages.

I still don't know why exactly Autofac or Ninject would mess with how attributes and validation work, without me explicitly telling them to do so, but at this point I don't even care.

Hopefully this helps someone!

Upvotes: 1

Related Questions