[转]DbFirst数据验证

转自:Data Validate 之 Data Annotation

  1. 什么是Data Annotation ?
  2. 如何使用 ?
  3. 自定义Validate Attribute
  4. EF  Db first中使用Data Annotation
  5. asp.net MVC中使用Data Annotation

什么是Data Annotation ?

貌似没听过,但肯定见过

所属程序集:System.ComponentModel.DataAnnotations

DataAnnotation code:

复制代码
  public class Product
    {
    
        [Required]
        [StringLength(10,MinimumLength =5)]
        public string Name { get; set; }

        [Required]
        public decimal? UnitPrice { get; set; }
    }
复制代码

没错,就是给类的属性加上描述性的验证信息,

如何使用这些信息 为我们自己所用呢?

当然是先自己想办法了,

添加辅助类:

复制代码
    public class ModelValidationError
    {
        public string FieldName { get; set; }
        public string Message { get; set; }
    }
    public static class DataAnnotationHelper
    {
        public static IEnumerable<ModelValidationError> IsValid<T>(this T o)
        {
            var descriptor = GetTypeDescriptor(typeof(T));

            foreach (PropertyDescriptor propertyDescriptor in descriptor.GetProperties())
            {
                var validations = propertyDescriptor.Attributes.OfType<ValidationAttribute>();
                foreach (var validationAttribute in validations)
                {
                    var v = propertyDescriptor.GetValue(o);

                    if (!validationAttribute.IsValid(v))
                    {
                        yield return new ModelValidationError() { FieldName = propertyDescriptor.Name, Message = validationAttribute.FormatErrorMessage(propertyDescriptor.Name) };
                    }
                }
            }
        }
        private static ICustomTypeDescriptor GetTypeDescriptor(Type type)
        {
            return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
        }
    }
复制代码

如何使用:

复制代码
 class Program
    {
        static void Main(string[] args)
        {
            Product product = new Product();
            foreach (var item in product.IsValid())
            {
                Console.WriteLine("FieldName:{0} Error Message:{1}", item.FieldName, item.Message);
            }
            Console.ReadKey();
        }
    }
复制代码

自定义ValidateAttribute

.net 提供的 ValidateAttribute不够用怎么搞?自定义呗,

复制代码
    public class PriceAttribute : ValidationAttribute
    {
        public double MinPrice { get; set; } 

        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return false;
            }
            var price = (double)value;

            if (price < MinPrice)
            {
                return false;
            }
            return true;
        }
        public override string FormatErrorMessage(string name)
        {
            return "Min Price is "+MinPrice;
        }
    }
复制代码

使用方法和.net 提供的一样:

复制代码
    public class Product
    {
    
        [Required]
        [StringLength(10,MinimumLength =5)]
        public string Name { get; set; }

        [Required]
        [Price(MinPrice =2)]
        public decimal? UnitPrice { get; set; }
    }
复制代码

EF  Db first中使用Data Annotation

实际应用中遇到的问题:

在使用EF DBfirst的时候,实体类的validate attribute,一不小心经常会被覆盖掉,如何解决

巧妙使用partial 类

复制代码
    public class ProductMetaData
    {
        [Required]
        [StringLength(10, MinimumLength = 5)]
        public string Name { get; set; }

        [Required]
        [Price(MinPrice = 2)]
        public decimal? UnitPrice { get; set; }
    }
    [MetadataType(typeof(ProductMetaData))]
    public partial class Product
    {

    }
    public partial class Product
    {
        public string Name { get; set; }

        public decimal? UnitPrice { get; set; }
    }
复制代码

这样做在大多数情况下是没有问题的。但是仅仅是这样,还不能解决所有问题。一般情况下Business Model和MetadataType是不在同一个Assembly里面,这时候你就无法以partial类的形式来扩展Business Model。所以我们就需要有一套机制来延迟注册Business Model与MetadataType的映射关系。通过MVC源码的分析,我们可以通过扩展DataAnnotationsModelMetadataProvider的GetTypeDescriptor方法来解决这个问题(http://www.cnblogs.com/hjf1223/archive/2010/07/27/independency_metadatatype.html)。

asp.net mvc 中data annotation的使用:

asp.net mvc中对data annotation具有原生的支持,

默认情况下,ASP.NET MVC框架在模型绑定时执行验证逻辑。
模型邦定器一旦完成对模型属性的更新,就会利用当前的模型元数据获得模型的所有验证器。这运行时提供了一个验证其 (DataAnnotationModelValidator)来与注解一同工作。这个模型验证器会找到所有的验证特性并执行它们包含的验证逻辑。 ModelBinder捕获所有失败的验证其规则并把它们放入ModelState中。
 
模型绑定的主要产物就是ModelState(Controller的属性)。
这个对象不仅包含了用户所有想放入模型属性里的值,也包括与每一个属性相关联的所有错误,和模型本身的错误,如果存在错误ModelState.IsValid返回false。
 
ModelState("LastName").Errors[0].ErrorMessage;//查看LastName属性的错误信息
View中查看:@Html.ValadationMessageFor(m=>m.LastName)
 
在编辑操作的PostAction中,可以先使用ModelState.IsValid属性判断是否通过验证,再不同对待。
 
 
 
 
参考文档:
http://www.asp.net/mvc/overview/older-versions-1/models-data/validation-with-the-data-annotation-validators-cs
 
http://www.cnblogs.com/xinchuang/archive/2013/06/06/3120482.html
 
http://www.cnblogs.com/kevin-kingdom/archive/2012/12/07/2807138.html
 
http://www.cnblogs.com/hjf1223/archive/2010/11/07/independent-dataannotation-validation.html
原文地址:https://www.cnblogs.com/xuejianxiyang/p/6221559.html