用反射给属性赋值,例XML用反射给属性赋值

首先先把xml的节点读取出来

private XmlNode ReadXmlNodeRoot(String xml)
        {

            XmlNode xmlNodeRoot = null;

            if (!String.IsNullOrEmpty(xml))
            {
                XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();

                xmlReaderSettings.IgnoreComments = true;

                XmlReader xmlReader = XmlReader.Create(new StringReader(xml), xmlReaderSettings);

                XmlDocument xmlDocument = new XmlDocument();

                xmlDocument.Load(xmlReader);

                XmlNodeList xmlNodeList = xmlDocument.SelectNodes("root");

                if (null != xmlNodeList && xmlNodeList.Count == 1)
                {
                    xmlNodeRoot = xmlNodeList[0];
                }
            }

            return xmlNodeRoot;

        }

现在要把xml的转化为数据实体,如果手动赋值会非常麻烦,如下

this.ModelData1=xmlNodeRoot["rootName1"].InnerText;
this.ModelData2=xmlNodeRoot["rootName2"].InnerText;
this.ModelData3=xmlNodeRoot["rootName3"].InnerText;

当节点多的时候,这样赋值会非常麻烦,而且必须知道xml中的所有节点名点,如果xml中少传一个节点,并且赋值是没有做判断,那么更会报异常,程序出错。

下面用发射来动态生成数据实体,就会非常简单

        private void SetPropertyValue(XmlNode xmlNodeRoot)
        {
            if (null != xmlNodeRoot && xmlNodeRoot.ChildNodes.Count > 0)
            {
                PropertyInfo[] propertyInfos = this.GetType().GetProperties();

                if (null != propertyInfos && propertyInfos.Length > 0)
                {
                    Int32 propertyInfoCount = propertyInfos.Length;

                    for (Int32 index = 0; index < propertyInfoCount; index++)
                    {
                        List<XmlElementExAttribute> dataattributelist= this.GetCallCenterAttribute<XmlElementExAttribute>(propertyInfos[index]);

                        if (null != dataattributelist&& dataattributelist.Count > 0)
                        {
                            XmlNode xmlNode = xmlNodeRoot.SelectSingleNode(String.Format("/{0}/{1}", xmlNodeRoot.Name, dataattributelist[0].XmlElementName));

                            if (null != xmlNode)
                            {
                                propertyInfos[index].SetValue(this, xmlNode.InnerText, null);
                            }
                        }
                    }
                }
            }
        }

//根据propertyInfo来获取XmlElementExAttribute
        private List<T> GetCallCenterAttribute<T>(PropertyInfo propertyInfo) where T : class
        {
            List<T> customAttributeList = new List<T>();

            if (null != propertyInfo)
            {
                Object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(T), true);

                foreach (T singleCustomAttribute in customAttributes)
                {
                    if (null != singleCustomAttribute)
                    {
                        customAttributeList.Add(singleCustomAttribute);
                    }
                }
            }

            return customAttributeList;
        }

当用反射给数据实体赋值时,在定义实体时还要注意标注特性

private string pepolename;

[XmlElementExAttribute("姓名", "xmlppepolename")]
public string Pepolename
{
set
{
this.pepolename=value;
}
get
{
return this.pepolename;
}
}

可以看到上面属性中有一个XmlElementExAttribute的特性,此特性实际上是继承了反射基类Attribute,如下:

    [AttributeUsage( AttributeTargets.Property , AllowMultiple = false )]
    public class XmlElementExAttribute : Attribute
    {
        #region Fields

        /// <summary>
        /// 描述
        /// </summary>
        private String description;

        /// <summary>
        /// XML 元素名称
        /// </summary>
        private String xmlElementName;

        #endregion

        #region Constructors

        /// <summary>
        /// PPTSCallCenterAttribute
        /// </summary>
        /// <param name="description">描述</param>
        /// <param name="typeName">类型名称</param>
        /// <param name="xmlElementName">XML元素名称</param>
        public XmlElementExAttribute( String description , String xmlElementName )
        {
            this.description = description;

            this.xmlElementName = xmlElementName;
        }

        #endregion

        #region Properties

        /// <summary>
        /// 描述
        /// </summary>
        public String Description
        {
            set
            {
                this.description = value;
            }
            get
            {
                return this.description;
            }
        }

        /// <summary>
        /// XML 元素名称
        /// </summary>
        public String XmlElementName
        {
            set
            {
                this.xmlElementName = value;
            }
            get
            {
                return this.xmlElementName;
            }
        }

        #endregion
    }

 

如果要在赋值时做数据验证,还要添加一个特性,并且调用下面的方法
  [VerifyString("姓名", false, "姓名验证失败")]

    public class VerifyString : VerifyDataAttribute
    {

        public VerifyString( String description , Boolean isNull , String errorMessage )
            : base( description , isNull , errorMessage )
        {
        }

        public override Boolean VerifyData( Object verifyContent )
        {
            #region

            if( null == verifyContent )
            {
                return false;
            }

            Boolean isVerifySuccess = false;

            if( !base.IsNull )
            {
                if( String.IsNullOrEmpty( verifyContent.ToString( ) ) )
                {
                    return false;
                }
            }

            isVerifySuccess = true;

            return isVerifySuccess;

            #endregion
        }

    }

如果要验证某个属性的正确性,类要继承于VerifyDataAttribute这个基类,具体怎样验证,就没有限制了
在验证时,调用下列方法

在给属性赋值时,加入下列方法

 

                        List<VerifyDataAttribute> verifyDataAttributeList = this.GetCallCenterAttribute<VerifyDataAttribute>(propertyInfos[index]);

                        if (null != verifyDataAttributeList && verifyDataAttributeList.Count > 0)
                        {
                            foreach (VerifyDataAttribute verifyData in verifyDataAttributeList)
                            {
//注意,此VerifyData是验证特性中的重写方法,可在数据实体中定义
                                if (!(verifyData.VerifyData(propertyInfos[index].GetValue(this, null))))
                                {
                                    throw new Exception(verifyData.ErrorMessage);
                                }
                            }
                        }

 

 

posted @ 2012-07-03 18:06  cqclassic  阅读(478)  评论(0编辑  收藏  举报