拿微信消息返回的示例数据实验
  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. WPF资源字典的使用【转】

    资源字典出现的初衷就在于可以实现多个项目之间的共享资源,资源字典只是一个简单的XAML文档,该文档除了存储希望使用的资源之外,不做任何其它的事情. 1.  创建资源字典 创建资源字典的过程比较简单,只 ...

  2. iOS开发UI篇—懒加载

    iOS开发UI篇—懒加载 1.懒加载基本 懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,写的是其get方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了, ...

  3. qthread 使用 signal 方法通信

    因为之间尝试过的 signal 机制,都是在 emit singnal_my() 的地方,直接调用了 slot 函数:相当于,slot 只是一个回调函数. 所以,在这里有点困惑,如果是要顺序执行完 s ...

  4. angularjs中ckeditor的destroy问题

    项目中,在切换了页面的tab页后会发现上传图片的操作报错,检查后发现问题根源是切换了tab页重新加载页面时ckeditor又会创建一次,这个时候的ckeditor已经不是第一次创建的那个了,所以上传图 ...

  5. SourceTree推送时,增加额外的远程仓库,不用每次都自定义粘贴复制网络

    一.命令行添加 二.软件界面可以查看到结果 更新,以上是代码添加了远程仓库,最近,找到了不用代码,直接在文件夹里写地址来添加的方式.直接上图了.

  6. MyBatis源码分析(1)——整体依赖关系图

    后续补充更新

  7. [NHibernate]存储过程的使用(一)

    目录 写在前面 文档与系列文章 Nhibernate中使用存储过程 一个例子 总结 写在前面 上篇文章一个小插曲,分析了延迟加载是如何解决N+1 select查询问题的.这篇开始介绍在nhiberna ...

  8. 关于js中的时间处理

    关于js编程, 主要是, 绝大部分是用 jquery. 但是, js原生的一些方法和属性也是要掌握的, 这个只是在 遇到的时候, 记一下就好了, 如: event的relatedTarget属性: 主 ...

  9. 10W -python

    计算2 3 4 加运算符 小于30 >>> new=[''.join(('2',op,'3')) for op in ops] >>> print(new) ['2 ...

  10. PHP5不重新编译,如何安装自带的未安装过的扩展,如soap扩展?

    在虚拟机的CentOS5.5中,一键安装了PHP运行环境,但发现并没有 soap 扩展,而近期项目用需要用到 webservice. 上述的一键安装(lamp0.4),其实是源码编译安装,PHP配置文 ...