微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

自定义验证器中将忽略MetadataType属性

如何解决自定义验证器中将忽略MetadataType属性

| (.NET 4.0 / WebForms / EF 4.1 POCO) 你好 我正在使用自定义验证程序将DataAnnotations与WebForms一起使用(源代码在下面)。 当我直接在生成的类中使用DataAnnotations时,一切都会很好。但是,当我在带有部分类Metadata类中使用DataAnnotations时,DataAnnotations属性似乎在验证中被绕过。我知道已正确识别了元数据,因为当我将数据保存在DbContext中时,它正在被验证,而EntityValidationErrors返回已验证的错误。 我进行了一些搜索,发现了这一点:(http://stackoverflow.com/questions/2657358/net-4-rtm-Metadatatype-attribute-ignored-when-using-validator/2657644#2657644)。不幸的是我的实现没有用。可能是我不知道在哪里打电话。我尝试在Metadata类的构造函数调用它,但没有用。
public static class MetadataTypesRegister
{
    static bool installed = false;
    static object installedLock = new object();

    public static void Install()
    {
        if (installed)
        {
            return;
        }

        lock (installedLock)
        {
            if (installed)
            {
                return;
            }

            // Todo: for debug purposes only (please remove in production)
            Assembly assembly = Assembly.GetExecutingAssembly();
            Type[] types = assembly.GetTypes();
            //------

            foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
            {
                foreach (MetadataTypeAttribute attrib in type.GetCustomAttributes(typeof(MetadataTypeAttribute),true))
                {
                    TypeDescriptor.AddProviderTransparent(
                        new AssociatedMetadataTypeTypeDescriptionProvider(type,attrib.MetadataClasstype),type);
                }
            }

            installed = true;
        }
    }
}
要验证的模型位于DataLayer.dll中,而DataAnnotationsValidator类位于Common.dll中。 这是我的DataAnnotationsValidator类:
[ToolBoxData(\"<{0}:DataAnnotationsValidator runat=server></{0}:DataAnnotationsValidator>\")]
public class DataAnnotationsValidator : BaseValidator
{

    private string _propertyName = string.Empty;
    public string PropertyName
    {
        get { return _propertyName; }
        set { _propertyName = value; }
    }

    public string _sourceType = string.Empty;
    public string SourceType
    {
        get { return _sourceType; }
        set { _sourceType = value; }
    }

    public ValidationDataType _type = ValidationDataType.String;
    public ValidationDataType Type
    {
        get { return _type; }
        set { _type = value; }
    }

    public string _cssError = string.Empty;
    public string CssError
    {
        get { return _cssError; }
        set { _cssError = value; }
    }

    protected override bool EvaluateIsValid()
    {   
        // get specified type for reflection
        Type objectType = System.Type.GetType(_sourceType,true,true);

        // get a property to validate
        PropertyInfo prop = objectType.GetProperty(_propertyName);

        // get the control to validate
        TextBox control = this.FindControl(this.ControlTovalidate) as TextBox;

        object valueTovalidate = null;
        if (control.Text != String.Empty)
        {
            if (Type == ValidationDataType.Double)
                valueTovalidate = double.Parse(control.Text);
            else if (Type == ValidationDataType.Integer)
                valueTovalidate = int.Parse(control.Text);
            else if (Type == ValidationDataType.Date)
                valueTovalidate = DateTime.Parse(control.Text);
            else if (Type == ValidationDataType.Currency)
                valueTovalidate = decimal.Parse(control.Text);
            else
                valueTovalidate = control.Text;
        }

        CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
        bool result = true;
        try
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            // The custom validator can return only one error message. Because the field model being validated can have more than 
            // one DataAnnotation validation (required,Range,RegularExpression,etc.) the DataAnnotationsValidator will return only the first 
            // error message that it evaluates.
            foreach (ValidationAttribute attr in prop.GetCustomAttributes(typeof(ValidationAttribute),true).OfType<ValidationAttribute>())
            {
                Thread.CurrentThread.CurrentCulture = currentCulture;

                if (!attr.IsValid(valueTovalidate))
                {
                    result = false;
                    var displayNameAttr = prop.GetCustomAttributes(typeof(displayNameAttribute),true).OfType<displayNameAttribute>().FirstOrDefault();
                    string displayName = displayNameAttr == null ? prop.Name : displayNameAttr.displayName;

                    ErrorMessage = attr.FormatErrorMessage(displayName);
                    break;
                }
            }
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = currentCulture;

            if (result)
            {
                if (!string.IsNullOrEmpty(CssError))
                    control.RemoveCssClass(CssError);
            }
            else
            {
                if (!string.IsNullOrEmpty(CssError))
                    control.AddCssClass(CssError);
            }
        }
        return result;
    }
}
谢谢!!     

解决方法

        我在这里找到了解决方案(http://stackoverflow.com/questions/5600707/how-do-you-do-web-forms-model-validation)。 我修改了EvaluateIsValid方法的代码,以包括下面的代码以查找元数据属性:
    // get specified type for reflection
    Type objectType = System.Type.GetType(_sourceType,true,true);

    // check for the types that have MetadataType attribute because 
    // it is they who have the DataAnnotations attributes
    IEnumerable<MetadataTypeAttribute> mt = objectType.GetCustomAttributes(typeof(MetadataTypeAttribute),false).OfType<MetadataTypeAttribute>();
    if (mt.Count() > 0)
    {
        objectType = mt.First().MetadataClassType;
    }
一切顺利!     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。