EF & Model Validation & WinForm UI DataBinding

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值