问题
I have enabled unobtrusive client side validation in my app, and I have (something similar) to this model:
public class MyModel
{
    [Required]
    public string Name { get; set; }
    [Range(0, 100)]
    public int? Age { get; set; }
}
I have the following /Home/Index view:
@model MyModel
@using (Html.BeginForm("Test", "Home"))
{
    <div id="my-form"> 
        @Html.Partial("Model")
    </div>
    <input type="submit" value="Go" />
}
With the partial "Model":
@model MyModel
<div>
    @Html.LabelFor(x => x.Name)
    @Html.TextBoxFor(x => x.Name)
    @Html.ValidationMessageFor(x => x.Name)
</div>
<div>
    @Html.LabelFor(x => x.Age)
    @Html.TextBoxFor(x => x.Age)
    @Html.ValidationMessageFor(x => x.Age)
</div>
Everything is honky-dory, I get nice validation error messages.
Now I want to load the form / partial "Model" dynamically, i.e. remote the @Html.Partial and add the following:
<a href="#" id="load-form">Load the form</a>
<script type="text/javascript">
    $(function () {
        $("#load-form").click(function () {
            $.post(
                "/Home/Test",
                null,
                function (result) {
                    $("#my-form").html(result);
                    $.validator.unobtrusive.parse($("#my-form"));
                },
                "html");
        });
    });
</script>
Where /Home/Test is as simple as return Partial("Model", new MyModel());
But now the client side validation is no longer working, and if I look at the DOM and HTML returned, the data- attributes are not rendered, i.e.:
With Html.Partial() in /Home/Index
<div>    
    <label for="Name">Name</label>    
    <input data-val="true" data-val-required="The Name field is required." id="Name" name="Name" type="text" value="" />    
    <span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>    
</div>    
<div>    
    <label for="Age">Age</label>    
    <input data-val="true" data-val-number="The field Age must be a number." data-val-range="The field Age must be between 0 and 100." data-val-range-max="100" data-val-range-min="0" id="Age" name="Age" type="text" value="" />    
    <span class="field-validation-valid" data-valmsg-for="Age" data-valmsg-replace="true"></span>    
</div>
XHR response
<div>
    <label for="Name">Name</label>
    <input id="Name" name="Name" type="text" value="" />        
</div>
<div>
    <label for="Age">Age</label>
    <input id="Age" name="Age" type="text" value="" />    
</div>
Even if I add Html.EnableClientValidation(); and Html.EnableUnobtrusiveJavaScript(); explicitly in the partial view the validation stuff is not rendered.
How do I make my AJAX partial render the validation attributes and messages? Or what else could I be doing wrong?
回答1:
Ahh... simple :)
The @Html.BeginForm() must be in the same partial (which I guess is fair enough, since we are validating on a form), so:
/Home/Index view becomes:
@model MyModel
<div id="my-form"> 
    @Html.Partial("Model")
</div>
With the partial "Model":
@model MyModel
@using (Html.BeginForm("Test", "Home"))
{
    <div>
        @Html.LabelFor(x => x.Name)
        @Html.TextBoxFor(x => x.Name)
        @Html.ValidationMessageFor(x => x.Name)
    </div>
    <div>
        @Html.LabelFor(x => x.Age)
        @Html.TextBoxFor(x => x.Age)
        @Html.ValidationMessageFor(x => x.Age)
    </div>
    <input type="submit" value="Go" />
}
    回答2:
You dont need the form in your partial (theres an advantage at times to keeping it out, for ex. ajax forms and not having to rebind to a new form upon each load).
In your partial simply add
{ ViewContext.FormContext = new FormContext()} 
and the attributes will be written out.
来源:https://stackoverflow.com/questions/6124992/asp-net-mvc-3-unobtrusive-client-side-validation-with-dynamic-content