拿微信消息返回的示例数据实验
  1. var data = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId></xml>";

创建一个消息枚举
  1. /// <summary>
  2. /// 消息类型枚举
  3. /// </summary>
  4. public enum MsgType
  5. {
  6. /// <summary>
  7. /// 文本消息
  8. /// </summary>
  9. TEXT,
  10. /// <summary>
  11. /// 图片消息
  12. /// </summary>
  13. IMAGE,
  14. /// <summary>
  15. /// 语音消息
  16. /// </summary>
  17. VOICE,
  18. /// <summary>
  19. /// 视频消息
  20. /// </summary>
  21. VIDEO,
  22. /// <summary>
  23. /// 小视频消息
  24. /// </summary>
  25. SHORTVIDEO,
  26. /// <summary>
  27. /// 地理位置消息
  28. /// </summary>
  29. LOCATION,
  30. /// <summary>
  31. /// 链接消息
  32. /// </summary>
  33. LINK,
  34. /// <summary>
  35. /// 事件类型
  36. /// </summary>
  37. EVENT
  38. }

因为消息类型的大多数属性都相同,创建一个基类
  1. public abstract class BaseMsg
  2. {
  3. /// <summary>
  4. /// 开发者微信号
  5. /// </summary>
  6. public string ToUserName { get; set; }
  7. /// <summary>
  8. /// 发送方帐号(一个OpenID)
  9. /// </summary>
  10. public string FromUserName { get; set; }
  11. /// <summary>
  12. /// 消息创建时间 (整型)
  13. /// </summary>
  14. public string CreateTime { get; set; }
  15. /// <summary>
  16. /// 消息类型
  17. /// </summary>
  18. public MsgType MsgType { get; set; }
  19. }

再创建相应缺少类的属性
  1. /// <summary>
  2. /// 文本消息类型(例外)
  3. /// </summary>
  4. public class MsgText : BaseMsg
  5. {
  6. /// <summary>
  7. /// 文本消息内容
  8. /// </summary>
  9. public string Content { get; set; }
  10. /// <summary>
  11. /// 消息Id,64位整型
  12. /// </summary>
  13. public string MsgId { get; set; }
  14. }
  15. /// <summary>
  16. /// 图片消息类型(例外)
  17. /// </summary>
  18. public class MsgImage : BaseMsg
  19. {
  20. /// <summary>
  21. /// 图片链接
  22. /// </summary>
  23. public string PicUrl { get; set; }
  24. /// <summary>
  25. /// 消息Id,64位整型
  26. /// </summary>
  27. public string MsgId { get; set; }
  28. /// <summary>
  29. /// 图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
  30. /// </summary>
  31. public string MediaId { get; set; }
  32. }
  33. /// <summary>
  34. /// 语音消息类型(例外)
  35. /// </summary>
  36. public class MsgVoice : BaseMsg
  37. {
  38. /// <summary>
  39. /// 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
  40. /// </summary>
  41. public string MediaId { get; set; }
  42. /// <summary>
  43. /// 语音格式,如amr,speex等
  44. /// </summary>
  45. public string Format { get; set; }
  46. /// <summary>
  47. /// 消息id,64位整型
  48. /// </summary>
  49. public string MsgID { get; set; }
  50. }
  51. /// <summary>
  52. /// 视频消息类型(例外)
  53. /// </summary>
  54. public class MsgVideo : BaseMsg
  55. {
  56. /// <summary>
  57. /// 视频消息媒体id,可以调用多媒体文件下载接口拉取数据
  58. /// </summary>
  59. public string MediaId { get; set; }
  60. /// <summary>
  61. /// 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
  62. /// </summary>
  63. public string ThumbMediaId { get; set; }
  64. /// <summary>
  65. /// 消息id,64位整型
  66. /// </summary>
  67. public string MsgId { get; set; }
  68. }
  69. /// <summary>
  70. /// 小视频消息类型(例外)
  71. /// </summary>
  72. public class MsgShortVideo : BaseMsg
  73. {
  74. /// <summary>
  75. /// 视频消息媒体id,可以调用多媒体文件下载接口拉取数据
  76. /// </summary>
  77. public string MediaId { get; set; }
  78. /// <summary>
  79. /// 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
  80. /// </summary>
  81. public string ThumbMediaId { get; set; }
  82. /// <summary>
  83. /// 消息id,64位整型
  84. /// </summary>
  85. public string MsgId { get; set; }
  86. }
  87. /// <summary>
  88. /// 地理位置消息类型(例外)
  89. /// </summary>
  90. public class MsgLocation : BaseMsg
  91. {
  92. /// <summary>
  93. /// 地理位置维度
  94. /// </summary>
  95. public string Location_X { get; set; }
  96. /// <summary>
  97. /// 地理位置经度
  98. /// </summary>
  99. public string Location_Y { get; set; }
  100. /// <summary>
  101. /// 地图缩放大小
  102. /// </summary>
  103. public string Scale { get; set; }
  104. /// <summary>
  105. /// 地理位置信息
  106. /// </summary>
  107. public string Label { get; set; }
  108. /// <summary>
  109. /// 消息id,64位整型
  110. /// </summary>
  111. public string MsgId { get; set; }
  112. }
  113. /// <summary>
  114. /// 链接消息类型(例外)
  115. /// </summary>
  116. public class MsgLink : BaseMsg
  117. {
  118. /// <summary>
  119. /// 消息标题
  120. /// </summary>
  121. public string Title { get; set; }
  122. /// <summary>
  123. /// 消息描述
  124. /// </summary>
  125. public string Description { get; set; }
  126. /// <summary>
  127. /// 消息链接
  128. /// </summary>
  129. public string Url { get; set; }
  130. /// <summary>
  131. /// 消息id,64位整型
  132. /// </summary>
  133. public string MsgId { get; set; }
  134. }

加载消息,转换成对象
  1. public static BaseMsg LoadMsg()
  2. {
  3. var data = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId></xml>";
  4. var doc = XElement.Parse(data);
  5. MsgType msgtype = (MsgType)Enum.Parse(typeof(MsgType), doc.Element("MsgType").Value.ToUpper());
  6. //MsgType msgtype = (MsgType)Enum.Parse(typeof(MsgType), "TEXT");
  7. switch (msgtype)
  8. {
  9. case MsgType.IMAGE:
  10. return ConvertObj<MsgImage>(data);
  11. case MsgType.LINK:
  12. return ConvertObj<MsgLink>(data);
  13. case MsgType.LOCATION:
  14. return ConvertObj<MsgLocation>(data);
  15. case MsgType.VIDEO:
  16. return ConvertObj<MsgVideo>(data);
  17. case MsgType.SHORTVIDEO:
  18. return ConvertObj<MsgShortVideo>(data);
  19. case MsgType.TEXT:
  20. return ConvertObj<MsgText>(data);
  21. case MsgType.EVENT:
  22. return null;
  23. default:
  24. return ConvertObj<BaseMsg>(data);
  25. }
  26. }

利用反射
  1. public static T ConvertObj<T>(string xmlstr)
  2. {
  3. try
  4. {
  5. var xml = XElement.Parse(xmlstr);
  6. var type = typeof(T);
  7. var t = Activator.CreateInstance<T>(); //动态创建实例,相当于 new T()
  8. var tousername = type.GetProperty("ToUserName");//搜索具有指定名称的公共属性
  9. //PropertyInfo.SetValue(object obj, object value, object[] index)
  10. tousername.SetValue(t, Convert.ChangeType(xml.Element("ToUserName").Value, tousername.PropertyType), null);
  11. xml.Element("ToUserName").Remove();
  12. var fromusername = type.GetProperty("FromUserName");
  13. fromusername.SetValue(t,
  14. Convert.ChangeType(xml.Element("FromUserName").Value, fromusername.PropertyType), null);
  15. xml.Element("FromUserName").Remove();
  16. var createtime = type.GetProperty("CreateTime");
  17. createtime.SetValue(t, Convert.ChangeType(xml.Element("CreateTime").Value, createtime.PropertyType), null);
  18. xml.Element("CreateTime").Remove();
  19. var msgType = type.GetProperty("MsgType");
  20. var msgtype = xml.Element("MsgType").Value;
  21. //msgType.SetValue()  是枚举,参数要改变
  22. msgType.SetValue(t, (MsgType)Enum.Parse(typeof(MsgType), msgtype.ToUpper()), null);
  23. xml.Element("MsgType").Remove();
  24. foreach (var element in xml.Elements())
  25. {
  26. var pr = type.GetProperty(element.Name.ToString());
  27. pr.SetValue(t, Convert.ChangeType(element.Value, pr.PropertyType), null);
  28. }
  29. return t;
  30. }
  31. catch (Exception)
  32. {
  33. return default(T);
  34. throw;
  35. }
  36. }

 


C#回顾 - 8.利用反射动态创建对象的更多相关文章

  1. C# 利用反射动态创建对象——带参数的构造函数和String类型

    C# 利用反射动态创建对象——带参数的构造函数和String类型 最近笔者有一个想法需要利用反射动态创建对象(如string,int,float,bool,以及自定义类等)来实现,一直感觉反射用不好, ...

  2. C#利用反射动态创建对象 带参数的构造函数和String类型 (转载)

    最近笔者有一个想法需要利用反射动态创建对象(如string,int,float,bool,以及自定义类等)来实现,一直感觉反射用不好,特别是当构造函数带参数的时候.MSDN上给出的例子十分复杂,网上的 ...

  3. C# 利用反射动态创建对象[摘录]

    摘自:http://hi.baidu.com/yangyuhang/blog/item/f12ea90e13f214e336d12250.html 在VS.Net中,有很多种方法动态调用对象的构造函数 ...

  4. 【转】C# 利用反射动态创建对象

    http://www.cnblogs.com/Jan_Dai/archive/2010/11/09/1872812.html Activator.CreateInstance(Type.GetType ...

  5. C# 利用反射动态加载dll

    笔者遇到的一个问题,dll文件在客户端可以加载成功,在web端引用程序报错.解决方法:利用反射动态加载dll 头部引用加: using System.Reflection; 主要代码: Assembl ...

  6. C# 知识点笔记:IEnumerable<>的使用,利用反射动态调用方法

    IEnumerable<T>的使用 创建一个IEnumerable对象 List<string> fruits = new List<string> { " ...

  7. .Net Core利用反射动态加载类库的方法(解决类库不包含Nuget依赖包的问题)

    在.Net Framework时代,生成类库只需将类库项目编译好,然后拷贝到其他项目,即可引用或动态加载,相对来说,比较简单.但到了.Net Core时代,动态加载第三方类库,则稍微麻烦一些. 一.类 ...

  8. protobuf在java应用中通过反射动态创建对象(DynamicMessage)

    ---恢复内容开始--- 最近编写一个游戏用到protobuf数据格式进行前后台传输,苦于protobuf接受客户端的数据时是需要数据类型的如xxx.parseForm(...),这样就要求服务器在接 ...

  9. StructureMap.dll 中的 GetInstance 重载 + 如何利用 反射动态创建泛型类

    public static T GetInstance<T>(ExplicitArguments args); // // Summary: // Creates a new instan ...

随机推荐

  1. 【OpenJudge 1793】矩形覆盖

    http://noi.openjudge.cn/ch0405/1793/ 好虐的一道题啊. 看数据范围,一眼状压,然后调了好长时间QwQ 很容易想到覆盖的点数作为状态,我用状态i表示至少覆盖状态i表示 ...

  2. Word密码破解工具字典攻击用来干什么的

    AOPR全称Advanced Office Password Recovery作为一款专业的Word密码破解工具,是通过暴力破解的方式帮助用户迅速恢复各种Word文档的密码,其中常常会用到字典攻击,这 ...

  3. 【CityHunter】基于LBS的AR体感游戏设计理念

    本人目前还不是游戏行业的圈内人士,并不懂得,游戏行业的生态圈,也不懂得,所谓的什么“中国市场环境”.所以不敢发表关于这方面的见解,不过我在这里想要插一句话,就是我认为啊,行业内,人与人之间还是有分层次 ...

  4. [转载]抓包,端口镜像,monitor session命令(转)

    原文地址:抓包,端口镜像,monitor session命令(转)作者:浮云皓月 一.SPAN简介 SPAN技术主要是用来监控交换机上的数据流,大体分为两种类型,本地SPAN和远程SPAN. --Lo ...

  5. eclipse中SSH三大框架环境搭建<二>

    通过上一篇博客我们可以轻松搭建strtus2的环境,接下来由我来继续介绍spring的环境搭建以及spring注入的简单使用 相关链接:eclipse中SSH三大k框架环境搭建<一> ec ...

  6. ArcGIS Server开发教程系列(7)使用ArcGIS API for Javascript-Hello World

    ArcGIS API for Javascript  API下载地址:http://support.esrichina-bj.cn/2011/0223/960.html 选择最新的下载就好了,目前是3 ...

  7. Gdb调试多进程程序

    Gdb调试多进程程序 程序经常使用fork/exec创建多进程程序.多进程程序有自己独立的地址空间,这是多进程调试首要注意的地方.Gdb功能强大,对调试多线程提供很多支持. 方法1:调试多进程最土的办 ...

  8. 原生JS常用代码汇总

    数组相关 var codes = new Array( ); //创建数组codes.length //数组长度 动态插入数组 codes.push(value);

  9. 【转载】借助GitHub托管你的项目代码

    PS:自己关注博客园有2年之久了,不久前才申请注册账号.GitHub也差不多一年多了,因英语水平刚刚及格,所以去GitHub没有博客园多,也是几个月前才注册了账号,前几天休息时看到 EdisonCho ...

  10. 《大道至简》第一章读后感--JAVA语言伪代码形式

    import.java.大道至简.*; //一·愚公移山 import.java.愚公移山.*; public class YuGongYiShan { //原始需求:惩山北之塞,出入之迂 //项目沟 ...