I have a view model with an Email address property and a Confirm Email Address property, as shown below:
public class UserNewModel
{
[Required]
[StringLength(100)]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email Address")]
public string EmailAddress { get; set; }
[Required]
[StringLength(100)]
[DataType(DataType.EmailAddress)]
[Display(Name = "Confirm Email Address")]
[Compare("EmailAddress", ErrorMessage = "The email address and confirmation email address do not match.")]
public string ConfirmEmailAddress { get; set; }
}
There is a corresponding EditorTemplate strongly typed to this model:
@model SponsorworksSaaS.UI.Models.UserNewModel
<div class="editor-label">
@Html.LabelFor(m => m.EmailAddress)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.EmailAddress)
@Html.ValidationMessageFor(m => m.EmailAddress)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.ConfirmEmailAddress)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.ConfirmEmailAddress)
@Html.ValidationMessageFor(m => m.ConfirmEmailAddress)
</div>
My UserNewModel is then contain in other models, such as:
public class CompanyDetailsModel
{
....
/// <summary>
/// Used to capture the initial user account details when creating a new company
/// </summary>
[Display(Name = "Initial User Account")]
public UserNewModel NewCompanyUser { get; set; }
}
and the corresponding strongly typed view associated with this parent model uses @Html.EditorFor to display the editor template:
@model SponsorworksSaaS.UI.Models.CompanyDetailsModel
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true, "Company change was unsuccessful. Please correct the errors and try again.")
<div>
<fieldset>
<legend>Company Information</legend>
<div>
@Html.EditorFor(m => m.NewCompanyUser)
</div>
<p>
<input type="submit" name="btnSubmit" value="Save Company" />
</p>
</fieldset>
</div>
}
The compare validation at client side always fails for the email address. If I enter an identical string in the compare email address text box, it always shows the compare validation error message when I move the focus away. Even with the compare validation showing a fail at client side, if I submit the form the ModelState.IsValid is true, although I am not sure if there is any compare validation done at server side.
The view source generated is shown below:
<div class="editor-label">
<label for="NewCompanyUser_EmailAddress">Email Address</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-length="The field Email Address must be a string with a maximum length of 100." data-val-length-max="100" data-val-required="The Email Address field is required." id="NewCompanyUser_EmailAddress" name="NewCompanyUser.EmailAddress" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="NewCompanyUser.EmailAddress" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="NewCompanyUser_ConfirmEmailAddress">Confirm Email Address</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-equalto="The email address and confirmation email address do not match." data-val-equalto-other="*.EmailAddress" data-val-length="The field Confirm Email Address must be a string with a maximum length of 100." data-val-length-max="100" data-val-required="The Confirm Email Address field is required." id="NewCompanyUser_ConfirmEmailAddress" name="NewCompanyUser.ConfirmEmailAddress" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="NewCompanyUser.ConfirmEmailAddress" data-valmsg-replace="true"></span>
</div>
I have tried adding single quotes to the jquery.validate.unobtrusive.js file, as suggested on other posts here, but this did not fix the problem.
element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];
changed to:
element = $(options.form).find(":input[name='" + fullOtherName + "']")[0];
I have also tried using both the min and full js files, but the problem remains the same. In fact if I add some jquery to the ready function:
$(function () {
var e1 = $('form').find(":input[name=*.EmailAddress]");
var e2 = $('form').find(":input[name='*.EmailAddress']");
alert(e1);
alert(e1[0]);
alert(e2);
alert(e2[0]);
});
The alert(e2[0]) returns undefined, but alert(e1[0]) returns the expected text box element.
Turns out it was the known error in the jquery.validate.unobtrusive.js file. I forgot to clean out the old cached copy! D’oh! The offending line of code is on line 284 in my version of the file 9in case anybody else needs to change it). A search for equalto will get close to the correct section of code.
A clean solution from Visual Studio was enough to do the trick.
I haven’t managed to get the jquery.validate.unobtrusive.min.js file to work though, despite changing the
to
Note the single quotes around the “+d+” in the find method call.