Asp.net mvc ASP.NET MVC 2中的元数据类型和客户端验证

Asp.net mvc ASP.NET MVC 2中的元数据类型和客户端验证,asp.net-mvc,validation,modelmetadata,Asp.net Mvc,Validation,Modelmetadata,在ASP.NET MVC 2中,继承的属性和元数据类型似乎不适用于客户端验证。 元数据类型的验证在服务器上按预期工作,但由于某些原因,它没有为其生成适当的客户端脚本。客户端验证按预期对PersonView上设置了DataAnnotations属性的属性生效,因此我知道客户端验证处于活动状态,并且有效有人知道是否可以或如何修复吗? 以下是我们所拥有的: public abstract class PersonView { public string FirstName { get; set

在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.NETMVC2站点,正如您所描述的,并且我已经对必需属性和基于正则表达式的属性进行了客户端验证,效果很好。不过,目前我自己的验证器(源自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>
<% } %>

相册详细信息
相册标题:
这张专辑是公开的吗
这将导致以下内容输出到表单标记下方的客户端(格式清晰):


//

据一位微软官员称,这是ASP.NET MVC 2中的一个漏洞。我得到了下面的链接,虽然场景不完全相同,但似乎是相同的问题。据我所知,它与内置属性和DataAnnotations模型元数据提供程序有关。该链接称,他们将尝试在ASP.NETMVC3中解决该问题


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

对不起我的英语

我很好奇,你解决过这个问题吗?@SkippyFire:看看我的答案!很难说我什么时候没有Album类的其他部分,但是你真的是从Album部分中的基类继承的吗?看看我的答案。@Kristofer Ahl-Album是我实体框架数据模型的一部分,所以是的,它肯定是从以下内容继承的:
公共部分类Album:global::System.Data.Objects.DataClasses.EntityObject
(来自附加到.edmx文件的Designer.cs文件),并且包含修饰的标题属性(
[EdmScalarPropertyAttribute(IsNullable=false)]
[DataMemberAttribute()]
)很高兴您发现了这个问题。感谢您发布更新!@SkippyFire和@Kristofer,到目前为止有没有关于这个问题在任何版本中得到解决的消息?这个问题在v3中得到解决了吗?根据我的测试,我似乎仍然是个问题。
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;
    }
}
ModelMetadataProviders.Current = new CustomModelMetadataProvider();