5

继承的属性和 MetadataType 似乎不适用于 ASP.NET MVC 2 中的客户端验证。

我们的 MetadataTypes 验证在服务器上按预期工作,但由于某种原因,它没有为它生成适当的客户端脚本。对于在 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 中的错误吗?

4

3 回答 3

2

根据 Microsoft 官员的说法,这是 ASP.NET MVC 2 中的一个错误。我得到了下面的链接,虽然场景不完全相同,但似乎是同一个问题。据我所知,它与继承的属性和 DataAnnotations 模型元数据提供程序有关。该链接说他们将尝试解决 ASP.NET MVC 3 中的问题。

Asp.net MVC 2 RC2:客户端验证不适用于覆盖的属性

于 2010-03-31T07:34:43.980 回答
1

也许为时已晚,但这是我设法解决此错误的方式。
我创建了一个自定义模型元数据提供程序,它继承自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();

对不起我的英语不好!

于 2011-01-28T18:07:40.260 回答
0

你确定吗?我已经按照您的描述设置了一个 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">&nbsp;</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>
于 2010-03-26T11:44:20.970 回答