ASP.NET MVC 2 中的 MetadataType 和客户端验证
-
21-09-2019 - |
题
继承的属性和 MetadataType 似乎不适用于 ASP.NET MVC 2 中的客户端验证。
我们的元数据类型的验证在服务器上按预期工作,但由于某种原因,它没有为其生成适当的客户端脚本。对于在 PersonView 上设置了 DataAnnotations 属性的属性,客户端验证按照预期启动,因此我知道客户端验证处于活动状态并且有效。 有谁知道是否可以修复或如何修复?
这是我们所拥有的:
public abstract class PersonView
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
[Required] public string PhoneNumber { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressZipCode { get; set; }
public string AddressCity { get; set; }
public string AddressCountry { get; set; }
}
[MetadataType(typeof(CustomerViewMetaData))]
public class CustomerView : PersonView {}
[MetadataType(typeof(GuestViewMetaData))]
public class GuestView : PersonView {}
public class GuestViewMetaData
{
[Required(ErrorMessage = "The guests firstname is required")] public string FirstName { get; set; }
[Required(ErrorMessage = "The guests lastname is required")] public string LastName { get; set; }
}
public class CustomerViewMetaData
{
[Required(ErrorMessage = "The customers firstname is required")] public string FirstName { get; set; }
[Required(ErrorMessage = "The customers lastname is required")] public string LastName { get; set; }
[Required(ErrorMessage = "The customers emails is required")] public string Email { get; set; }
}
正如你所看到的,里面没有什么奇特或奇怪的东西......可以修复吗? 这是 ASP.NET MVC 2 中的错误吗?
解决方案
据微软官方透露 这是 ASP.NET MVC 2 中的一个错误. 。我收到了下面的链接,虽然场景不完全相同,但似乎是同一个问题。据我所知,它与继承属性和 DataAnnotations 模型元数据提供程序有关。该链接表示他们将尝试修复 ASP.NET MVC 3 中的问题。
其他提示
也许为时已晚,但是这是我设法解决这个bug的方式。结果 我已经创建了从<强> DataAnnotationsModelMetadataProvider 强>继承的自定义模型的元数据提供者,并覆盖在 CreateMetadata 方式。 的问题是,在的值的 containerType 强>参数指向基类而不是指向继承的类。 下面是代码
public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
if (modelAccessor != null && containerType != null)
{
FieldInfo container = modelAccessor.Target.GetType().GetField("container");
if (containerType.IsAssignableFrom(container.FieldType))
containerType = container.FieldType;
}
var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
return modelMetadata;
}
}
最后,我们必须要注册在的Application_Start Global.asax中此自定义元数据提供商
ModelMetadataProviders.Current = new CustomModelMetadataProvider();
对不起,我的英语!
您确定吗?我有一个ASP.NET MVC 2网站设置为你描述和我有正常工作必需的和基于正则表达式的属性的客户端验证。
:它不与我自己验证的时刻(从ValidationAttribute派生)的工作,虽然[MetadataType(typeof(AlbumMetadata))]
public partial class Album {}
public class AlbumMetadata {
[Required(ErrorMessage = "You must supply a caption that is at least 3 characters long.")]
[MinLength(3, ErrorMessage = "The caption must be at least {0} characters long.")]
[RegularExpression(@".{3,}")]
public string Caption { get; set; }
}
(MinLength
基本上提供了更明显的方式看到发生了什么在正则表达式的属性,将其用于测试后加)
我然后在我的视图以下内容:
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Album details</legend>
<div class="form_row">
<label for="Caption" class="left_label">Album caption:</label>
<%= Html.TextBox("Caption", Model.Caption, new { @class = "textbox" })%>
<%= Html.ValidationMessage("Caption", "*") %>
<div class="cleaner"> </div>
</div>
<div class="form_row">
<label for="IsPublic" class="left_label">Is this album public:</label>
<%= Html.CheckBox("IsPublic", Model.IsPublic) %>
</div>
<div class="form_row">
<input type="submit" value="Save" />
</div>
</fieldset>
<% } %>
这导致以下被输出到下面的表格标签客户端(格式化为清楚起见):
<script type="text/javascript">
//<![CDATA[
if (!window.mvcClientValidationMetadata)
{ window.mvcClientValidationMetadata = []; }
window.mvcClientValidationMetadata.push({
"Fields":[
{"FieldName":"Caption",
"ReplaceValidationMessageContents":false,
"ValidationMessageId":"Caption_validationMessage",
"ValidationRules":[
{"ErrorMessage":"You must supply a caption that is at least 3 characters long.",
"ValidationParameters":{},
"ValidationType":"required"},
{"ErrorMessage":"The field Caption must match the regular expression \u0027.{3,}\u0027.",
"ValidationParameters":{"pattern":".{3,}"},
"ValidationType":"regularExpression"}]
}],
"FormId":"form0","ReplaceValidationSummary":false});
//]]>
</script>