1

I'm using a mostly new jquery validation stack with ASP.NET MVC 5

  • jquery-1.10.2
  • jquery.validate 1.13.1
  • jquery.unobtrusive-ajax.js 3.2.2
  • jquery.validate.unobtrusive.js 3.2.2

I'm using an Ajax form with a partial view and for some reason the compare validation attribute works on the first post but not on subsequent posts. Here is my example:

Model

public class TestModel
{
    [Required]
    public string NewPassword { get; set; }

    [Required]
    [Compare("NewPassword")]
    public string ConfirmPassword { get; set; }
}

Index.cshtml

@model TestModel

<h2>Index</h2>

@Html.Partial("_TestForm", Model)

_TestForm.cshtml

@model TestModel

@using (Ajax.BeginForm("FormTester", "Test", new AjaxOptions{UpdateTargetId = "formContainer"}))
{
    @Html.AntiForgeryToken()

    <div id="formContainer">
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(model => model.NewPassword, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.NewPassword)
                    @Html.ValidationMessageFor(model => model.NewPassword)
                </div>
            </div>
            
            <div class="form-group">
                @Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.ConfirmPassword)
                    @Html.ValidationMessageFor(model => model.ConfirmPassword)
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Save" class="btn btn-default" />
                </div>
            </div>
        </div>
    </div>    
}

And finally my test controller

public class TestController : Controller
{
    public ActionResult Index()
    {
        return View(new TestModel());
    }

    // GET: Test
    public ActionResult FormTester(TestModel model)
    {
        if(ModelState.IsValid)
        {
            return PartialView("_TestForm");
        }

        return PartialView("_TestForm", model);
    }
}

Steps to reproduce,

  1. Submit the form with valid data.
  2. When the form is returned, there should not be any validation messages: FirstSubmitSuccess
  3. Change both fields again to be the exact same but with different data and attempt to submit: SecondSubmitError
  4. Now the only way to submit the form again is to change the second field (or both) to be the original value:

SecondSubmitSuccess

I have no idea why this is happening or if there is even a workaround for this. Please help.

Community
  • 1
  • 1
akousmata
  • 1,005
  • 14
  • 34
  • Your dynamically adding new content with the `Ajax.BeginForm` method you you need to re-parse the validator. [Refer this answer](http://stackoverflow.com/questions/26542509/validate-dynamically-added-fields/26542591#26542591) –  Nov 12 '14 at 01:37
  • I will certainly test this, but why does the validation store and validate against the old data? Shouldn't it either validate against existing values or not validate at all? – akousmata Nov 12 '14 at 05:24
  • 1
    Because the validator parses each control of form when it is first loaded (and listens to changes in the values of those controls). Your ajax method replaces the existing controls and the validator knows nothing about the new ones until you remove the validator and re-parse again –  Nov 12 '14 at 05:30
  • This works and I +1'd your other answer. I guess I'm still confused. Clearly the validator knows _something_ about those new fields because it's still applying validation and showing the validation message. It wouldn't know where to display the message if it didn't have a handle on the form field itself which is why I suggested that the validation shouldn't work at all if what you say is true. – akousmata Nov 12 '14 at 15:07

0 Answers0