问题
When using any of the Input Extension Helper Methods, like @Html.TextboxFor, any Validation Attributes from your model are automatically generated by the Razor engine (via ClientValidationEnabled/UnobtrusiveJavaScriptEnabled).
For example, take the following case which works fine
Model:
[Required]
public string QuestionOne { get; set; }
View:
@Html.TextBoxFor(model => model.QuestionOne)
@Html.ValidationMessageFor(model => model.QuestionOne)
Generated Markup:
<input type="text" id="QuestionOne" name="QuestionOne" value=""
data-val="true" data-val-required="The QuestionOne field is required." >
<span class="field-validation-valid" data-valmsg-for="QuestionOne" data-valmsg-replace="true"></span>
In this case the attributes data-val="true"
& data-val-required="The QuestionOne field is required."
are picked up by Unobtrusive validation and the form element is successfully validated.
However, for extensibility reasons, I want to be able to generate the <input>
element myself instead of using TextBoxFor
. So my view would now look like this:
<input type="textbox"
id="@Html.IdFor(m => m.QuestionTwo)"
name="@Html.NameFor(m => m.QuestionTwo)"
value="@Model.QuestionTwo"
data-val="true" data-val-required="Selection is Required" />
@Html.ValidationMessageFor(model => model.QuestionTwo)
In this case, I'm faking the validation attribute output by just re-writing data-val="true" (etc)
by hand, but this would have to be expanded to cover every single case.
Here's a running Demo in .NET Fiddle
Q: Can I build /return a list of data-val-*
attributes for a given element?
回答1:
You can use the GetUnobtrusiveValidationAttributes()
method of HtmlHelper
to get the validation attributes associated with a specific property.
For example in the view
@{ var attributes = Html.GetUnobtrusiveValidationAttributes("QuestionTwo"); }
<input
type="textbox"
@foreach(var attr in attributes)
{
@:@attr.Key="@attr.Value"
}
id="@Html.IdFor(m => m.QuestionTwo)"
....
/>
Note the @:@attr.Key="@attr.Value"
line will give a warning (Missing attribute name) but will run correctly
Alternatively, you could use javaScript/jQuery to add the attributes
<script type="text/javascript">
var attributes = @Html.Raw(Json.Encode(attributes));
var input = $('#QuestionTwo');
for(var i in attributes) {
input.attr(i, attributes[i]);
}
</script>
I have forked the DotNetFiddle here to show the working code for both options.
While the above code shows how it can be done, you should not be doing that. The HtmlHelper
methods execute a lot of code your ignoring to ensure correct 2-way model binding, for example, the value
attribute is determined by first checking for a value in ModelState
, then in the ViewDataDictionary
, and only if the previous values do not exist, does it use the value of the property (the second part of TextBoxFor displaying initial value, not the value updated from code explains the behavior).
Except for the incorrect value
attribute, the code you have shown for the <input>
is the same as will be generated by simply using @Html.TextBoxFor(m => m.Question2)
. I assume your real case is different, but if you cannot make use of TextBoxFor()
and using an overload that accepts htmlAttributes
to generate the html you need, then the correct approach is to create your own HtmlHelper
method (and making use of existing methods in the HtmlHelper
class and System.Web.Mvc.Html
namespace)
来源:https://stackoverflow.com/questions/42999080/build-list-of-data-validation-attributes-for-a-given-element