EF & Model Validation & WinForm UI DataBinding

原创 2011年01月22日 21:50:00

asp.net mvc上使用EF(实体框架)中的Model Validation与UI自动绑定感觉还可以
最近碰到要做c/s结构系统,winform并没有直接支持,自己尝试实现一个

第一步
根据winform ui control上验证方式和数据绑定方式
EF上entity object实现IDataErrorInfo接口就可以了
第二步
利用DataAnnotation完成entity object上验证接口
DataAnnotation是.net内置的验证框架(其他验证框架有Castle Validator ,EntLib Validation Library)
使用DataAnnotation主要是为了减少第3方引用不方便,而且EF声明式验证需要结合MetaDataType关联验证类
.net内置的DataAnnotation中也有了

第三步
结合IDataErrorInfo和验证接口就可以达到的Model Validation与UI自动绑定的效果

第四步
EF设计器上自定义代码产生,他是利用T4来编写的,这样不用为每个entity object手动写patial类

 

系统最后采用的是EF+CAB(Composite UI Application Block)

因为采用Model Validation与UI自动绑定所以CAB这个框架下业务模块当然采用了MVC模式方式

 

 

验证部分实现代码如下:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Data.Objects.DataClasses;

namespace ChildrenModel
{
    class EntityObjectValidationProvider : IValidationProvider
    {
        private PropertyInfo[] properties;
        private object objectInstance;
        private Dictionary<PropertyInfo, string> failedProperties = new Dictionary<PropertyInfo, string>();
        public EntityObjectValidationProvider(object objectInstance)
        {
            this.objectInstance = objectInstance;
        }
        #region IValidationProvider Members

      
        public virtual bool IsValid()
        {

            Type thisClass = objectInstance.GetType();
            Type metaType = typeof(MetadataTypeAttribute);
            bool isDefined = Attribute.IsDefined(thisClass, metaType);
            if (!isDefined)
            {
                return true;
            }
            Attribute attribute = Attribute.GetCustomAttribute(thisClass, metaType);
            MetadataTypeAttribute metaAttribute = attribute as MetadataTypeAttribute;
            if (metaAttribute == null)
            {
                return true;
            }

            Type metaModelType = metaAttribute.MetadataClassType;


            properties = GetProperties(metaModelType);
            if (properties != null)
            {
                foreach (var prop in properties)
                {
                   
                    object[] objs = prop.GetCustomAttributes(typeof(ValidationAttribute), true);
                    foreach (var attrib in objs)
                    {
                        ValidationAttribute vAttrib = attrib as ValidationAttribute;
                        if (vAttrib!=null)
                        {
                           
                            object[] runWhenObjs =prop.GetCustomAttributes(typeof(RunWhenAttribute), true);
                          
                            RunWhen runWhen = RunWhen.Everytime;
                            foreach (var runWhenAttrib in runWhenObjs)
                            {
                                RunWhenAttribute rAttrib = runWhenAttrib as RunWhenAttribute;
                                if(rAttrib!=null)
                                {
                                    runWhen = runWhen & rAttrib.RunWhen;
                                }
                            }
                            if (runWhen != 0)
                            {
                               
                                Type modelType = objectInstance.GetType();
                                PropertyInfo modelPropInfo = modelType.GetProperty(prop.Name);
                                if (!vAttrib.IsValid(modelPropInfo.GetValue(objectInstance, null)))
                                {

                                    failedProperties[modelPropInfo] = vAttrib.ErrorMessage;
                                    return false;
                                }
                                else
                                {
                                    failedProperties[modelPropInfo] = string.Empty;
                                }
                                if (prop.GetType() == typeof(EntityObject))
                                                                {
                                    IValidationProvider ivp = Activator.CreateInstance(prop.GetType()) as IValidationProvider;
                                    ivp.IsValid();

                                }
                            }
                           
                        }

                    }
                }
            }
            return true;

        }

      
        public virtual String[] ValidationErrorMessages
        {
            get
            {
             
                return failedProperties.Values.ToArray();
            }
        }


        public virtual IDictionary PropertiesValidationErrorMessages
        {
            get { return failedProperties; }
        }

        #endregion
        private PropertyInfo[] GetProperties(Type type)
        {
            if (properties == null || properties.Length == 0)
                properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
          
            return properties;
        }
    }
}

最后T4产生的实体类效果的部分代码:

   /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    [EdmEntityTypeAttribute(NamespaceName="ChildrenModel", Name="Customer")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class Customer : EntityObject ,IValidationProvider, IDataErrorInfo
    {
    #region IDataErrorInfo Members
            string IDataErrorInfo.Error
            {
                get
                {
                    StringBuilder errors=new System.Text.StringBuilder();
                    foreach (string str in ValidationProvider.ValidationErrorMessages)
                    {
                        errors.Append(str);
                    }
                    return errors.ToString();
                }
            }
   
            string IDataErrorInfo.this[string column]
            {
                get
                {
                    Type t = this.GetType();
                    PropertyInfo info = t.GetProperty(column);
                    string errorMessage = string.Empty;
                    if (info != null)
                        errorMessage = ValidationProvider.PropertiesValidationErrorMessages[t.GetProperty(column)] as string;
                    if (errorMessage == null)
                        errorMessage = string.Empty;
                    return errorMessage;
                }
            }
            #endregion
            private IValidationProvider validationProvider;
            IValidationProvider ValidationProvider
            {
                get
                {
                    if (validationProvider == null)
                        validationProvider = new EntityObjectValidationProvider(this);
                   
                    return  validationProvider;
   
                }
            }
            #region IValidationProvider Members
   
            /// <summary>
            /// Performs the fields validation. Returns true if no
            /// validation error was found.
            /// </summary>
            /// <returns></returns>
            /// <remarks>Forwards the call to <see cref="ActualValidator"/>.</remarks>
            public virtual bool IsValid()
            {
                return ValidationProvider.IsValid();
            }
   
           
   
           
            public virtual String[] ValidationErrorMessages
            {
                get { return ValidationProvider.ValidationErrorMessages; }
            }
   
            public virtual IDictionary PropertiesValidationErrorMessages
            {
                get { return ValidationProvider.PropertiesValidationErrorMessages; }
            }
   
            #endregion

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

WinForm UI Validation

1) Just copy and paste this section of code to your project. We're using Reflection so you need to a...
  • jjhua
  • jjhua
  • 2012-07-07 22:53
  • 687

MVC 强类型传值Model。和弱类型传值ViewData[""]。及用EF进行增删查改(母版页的使用)

控制器 Home using System; using System.Collections.Generic; using System.Linq; using System.Web; using ...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

Generating EF Code First model classes from an existing database

Entity Framework Code First is a lightweight way to "turn on" data access for a simple CLR class. ...

ASP.NET MVC5 + EF6 入门教程 (5) Model和Entity Framework

上一节:ASP.NET MVC 5 入门教程 (4) View和ViewBag 下一节:ASP.NET MVC5 + EF6 入门教程 (6) View中的Razor使用 源码下载:点我下...

解决 无法检索“XXX.Models.XXX”的元数据,One or more validation errors were detected during model generation

在创建控制器时,在基架选项的模版下拉列表选择“包含读/写操作和视图的MVC控制器(使用Entity Framewordk)”选项,而在“模型类”下拉列表中选择其对应的Models的模型类别,在数据上下...

MVC 3 数据验证 Model Validation 详解

转载地址 http://www.cnblogs.com/jiagoushi/archive/2013/01/25/2876725.html 继续我们前面所说的知识点进行...

Real-Time Probabilistic Covariance Tracking With Efficient Model Update 阅读小结

文章:Real-Time Probabilistic Covariance Tracking With Efficient Model Update 作者:
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)