• 读取实体类的属性的备注作为表头的应用


    在做淘宝API的学习过程中,发现一个API的封装类库Top4NET对操作封装的比较好,试用了一下,效果非常不错,另外由于淘宝的API对象参数很多,多数是英文的,另一方面Top4NET的实体类对象备注信息很详细,因此可以考虑吧实体类的属性描述信息作为列表的表头说明使用。

    我们看到他的Domain里面的实体类信息描述很详细,代码如下所示:

    代码
        /// <summary>
        
    /// 商品结构
        
    /// </summary>
        [Serializable]
        [JsonObject]
        [XmlRoot(
    "item")]
        
    public class Item : BaseObject
        {
            
    /// <summary>
            
    /// 商品编号
            
    /// </summary>
            [JsonProperty("iid")]
            [XmlElement(
    "iid")]
            
    public string Iid { getset; }

            
    /// <summary>
            
    /// 商品地址
            
    /// </summary>
            [JsonProperty("detail_url")]
            [XmlElement(
    "detail_url")]
            
    public string DetailUrl { getset; }

            
    /// <summary>
            
    /// 商品数字编号
            
    /// </summary>
            [JsonProperty("num_iid")]
            [XmlElement(
    "num_iid")]
            
    public string NumIid { getset; }

            
    /// <summary>
            
    /// 商品标题
            
    /// </summary>
            [JsonProperty("title")]
            [XmlElement(
    "title")]
            
    public string Title { getset; }

            
    /// <summary>
            
    /// 卖家昵称
            
    /// </summary>
            [JsonProperty("nick")]
            [XmlElement(
    "nick")]
            
    public string Nick { getset; }

    我们看看Top4NET类库生成的字段描述信息,它是一个叫做Top4Net.xml的文件(VS自动生成出来的),结构如下所示:

     这些是很详细的类库备注信息,如果能在代码中读取对应的属性备注信息出来,那么各项内容的显示,就不需要太多的手工字段的转义工作了,虽然在性能上有点点损失,但是开发效率上会提高不少。

    现在的问题就是该如何才能正确读取到相关的信息,这个操作可以通过XML文档的检索实现的,我在测试的时候,发现可以通过3种方式来读取到正确节点的信息的。其中上面的Member中的Name第一个字符有T、P、M等字样,其中的T是类,P是属性,M是方法的意思。

    代码
            /// <summary>
            
    /// 根据类属性名称,获取对应的备注信息(如果键名不存在,返回空)
            
    /// </summary>
            
    /// <param name="classPropertyName">类全局名称(带命名空间)</param>
            
    /// <returns></returns>
            public static string GetPropertySummary(string classPropertyName)
            {
                
    string filePath =  Path.Combine(Application.StartupPath,"Top4Net.xml");
                
    string keyName = string.Format("//doc/members/member[@name='P:{0}']/summary", classPropertyName);

                XPathDocument doc 
    = new XPathDocument(filePath);
                XPathNavigator nav 
    = doc.CreateNavigator();
                XPathNodeIterator iterator 
    = nav.Select(keyName);

                
    string result = "";
                
    try
                {
                    
    if (iterator.MoveNext())
                    {
                        XPathNavigator nav2 
    = iterator.Current.Clone();
                        result 
    += nav2.Value;
                    }
                }
                
    catch (Exception ex)
                {
                    ;
                } 

                
    return result.Trim();
            }

            
    /// <summary>
            
    /// 根据类属性名称,获取对应的备注信息(如果键名不存在,返回空)
            
    /// </summary>
            
    /// <param name="classPropertyName">类全局名称(带命名空间)</param>
            
    /// <returns></returns>
            public static string GetPropertySummary2(string classPropertyName)
            {
                
    string filePath = Path.Combine(Application.StartupPath, "Top4Net.xml");
                
    string keyName = string.Format("//doc/members/member[@name='P:{0}']/summary", classPropertyName);

                XmlDocument document 
    = new XmlDocument();
                document.Load(filePath);

                
    string result = "";
                XmlNode node 
    = document.SelectSingleNode(keyName);
                
    if (node != null)
                {
                    result 
    = node.FirstChild.Value;
                }

                
    return result.Trim();
            }

            
    /// <summary>
            
    /// 根据类属性名称,获取对应的备注信息(如果键名不存在,返回空)
            
    /// </summary>
            
    /// <param name="classPropertyName">类全局名称(带命名空间)</param>
            
    /// <returns></returns>
            public static string GetPropertySummary3(string classPropertyName)
            {
                
    string strReturn = string.Empty;
                
    try
                {
                    
    string keyName = string.Format("P:{0}", classPropertyName);
                    
    string filePath = Path.Combine(Application.StartupPath, "Top4Net.xml");
                    XmlDocument document 
    = new XmlDocument();
                    document.Load(filePath);

                    XmlNodeList nodes 
    = document.GetElementsByTagName("member");
                    
    for (int i = 0; i < nodes.Count; i++)
                    {
                        
    //获得将当前元素的key属性
                        XmlAttribute attribute = nodes[i].Attributes["name"];
                        
    //根据元素的第一个属性来判断当前的元素是不是目标元素
                        if (attribute != null && (attribute.Value == keyName))
                        {
                            XmlNode node 
    = nodes[i].ChildNodes[0];
                            
    if (node != null)
                            {
                                strReturn 
    = node.FirstChild.Value;
                                
    break;
                            }
                        }
                    }
                }
                
    catch
                {
                    ;
                }

                
    return strReturn.Trim();
            }

    由于上述的方法参数classPropertyName是类的全称名字,因此我们需要通过反射方式获取对应的属性名称信息,由于属性名称的简称对我们也有用,因此编写一个API函数,返回Dictionary<string,string>类型即可。

    代码
            /// <summary>
            
    /// 获取类属性的名称和全称字典列表
            
    /// </summary>
            
    /// <param name="obj"></param>
            
    /// <returns></returns>
            public static Dictionary<stringstring> GetPropertyFullNameDict(object obj)
            {
                Dictionary
    <stringstring> dict = new Dictionary<stringstring>();
                Type t 
    = obj.GetType();

                PropertyInfo[] pi 
    = t.GetProperties();
                
    foreach (PropertyInfo info in pi)
                {
                    
    if (!dict.ContainsKey(info.Name))
                    {
                        dict.Add(info.Name, 
    string.Format("{0}.{1}", t.FullName, info.Name));
                    }
                }

                
    return dict;
            }

    最后我们在进一步封装,把实体类对象的备注信息取出来放到字典对象中,如下所示:

    代码
            /// <summary>
            
    /// 获取类属性名称和描述信息的对照字典
            
    /// </summary>
            
    /// <param name="obj">实体类对象</param>
            
    /// <returns></returns>
            public static Dictionary<stringstring> GetPropertyAliasDict(object obj)
            {
                Dictionary
    <stringstring> dict = new Dictionary<stringstring>();
                Dictionary
    <stringstring> propertyNameDict = XmlHelper.GetPropertyFullNameDict(obj);
                StringBuilder sb 
    = new StringBuilder();
                
    foreach (string simpleName in propertyNameDict.Keys)
                {
                    
    string summary = XmlHelper.GetPropertySummary(propertyNameDict[simpleName]);
                    
    if (string.IsNullOrEmpty(summary))
                    {
                        summary 
    = simpleName;//如果找不到对象的名称,那么取其属性名称作为Summary信息
                    }

                    
    if (!dict.ContainsKey(simpleName))
                    {
                        dict.Add(simpleName, summary);
                    }
                }
                
    return dict;
            }

    有了这个API函数,我们就可以随意的在界面中,通过极少的代码,实现表头中文化的自动转义了。下面我给我参考代码:

    代码
                //查询商品信息(不含类别)
                ItemsGetRequest itemReq = new ItemsGetRequest();
                itemReq.Fields 
    = "iid,title,nick,pic_url,cid,price,type,delist_time,post_fee,score,volume,location.city,location.state";
                itemReq.Query 
    = "笔记本";
                
    //itemReq.Cid = "14";
                itemReq.OrderBy = "volume:desc";
                itemReq.PageNo 
    = 1;
                itemReq.PageSize 
    = 40;

                
    #region 给显示控件添加别名解析

                
    //特殊字段采用手工修改
                this.winGridView1.AddColumnAlias("Created""创建时间");
                
    this.winGridView1.AddColumnAlias("Modified""修改时间");

                
    //其他字段代码自动转义
                Dictionary<stringstring> dictAlias = XmlHelper.GetPropertyAliasDict(new Item());
                
    foreach (string simpleName in dictAlias.Keys)
                {
                    
    this.winGridView1.AddColumnAlias(simpleName, dictAlias[simpleName]);
                }
                
    #endregion

                
    //显示列表信息
                ResponseList<Item> itemRsp = client.Execute(itemReq, new ItemListJsonParser());
                
    this.winGridView1.DataSource = itemRsp.Content;
                
    this.winGridView1.PrintTitle = "查询商品信息(不含类别)";

    最后给出一个测试程序的界面截图,供参考:

    取实体类备注信息作为界面展示用途,还可以应用在很多其他地方,淘宝Top4NET只是一个恰当的应用场景而已,对于大量备注完整的实体类,使用这些资源应该还是比较不错的选择。 

    主要研究技术:代码生成工具、会员管理系统、客户关系管理软件、病人资料管理软件、Visio二次开发、酒店管理系统、仓库管理系统等共享软件开发
    专注于Winform开发框架/混合式开发框架Web开发框架Bootstrap开发框架微信门户开发框架的研究及应用
      转载请注明出处:
    撰写人:伍华聪  http://www.iqidi.com 
        
  • 相关阅读:
    设计模式(十六):职责链模式
    设计模式(十五):状态模式
    设计模式(十四):命令模式
    设计模式(十三):模板模式
    设计模式(十二):观察者模式
    远程连接数据库常出现的错误解析
    [解决] Error Code: 1044. Access denied for user 'root'@'%' to database
    linux常用命令
    linux上svn项目管理,同步服务器,用户管理
    linux 磁盘分区
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/1689828.html
Copyright © 2020-2023  润新知