拿微信消息返回的示例数据实验
  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. datatable刷新表头

    使用jQuery的datatable生成表格数据,当需要改变表头时,调用Table.fnDestroy();再重新创建表头 var oTable = null; function initSettin ...

  2. eclipse注释快捷键(含方法注释)

    整段注释: /*public boolean executeUpdate(String sql) { System.out.println(sql); boolean mark=false; try ...

  3. Nginx简易配置文件(二)(反向代理)

    user nobody nobody; worker_processes 4; error_log logs/error.log; pid logs/nginx.pid; events { use e ...

  4. oracle中将自建用户下的所有表删除

    select 'drop table '||table_name||' ;' from user_tables;select 'drop sequence '||sequence_name||' ;' ...

  5. ionic 白屏

    昨天在发布新app的时候发现app在高版本的android的时候发现没有问题,在低版本的android 的时候发现存在白屏的情况,在run中alert,不能弹框,run不能运行, 参考这篇文章  ht ...

  6. Windows7微软官方原版镜像系统文件

    Windows7微软官方原版镜像系统 Windows 7 是由微软公司(Microsoft)开发的操作系统,核心版本号为Windows NT 6.1.Windows 7可供家庭及 商业工作环境.笔记本 ...

  7. 10月28日PHP基础知识测试题

    本试题共40道选择题,10道判断题,考试时间1个半小时 一:选择题(单项选择,每题2分): 1. LAMP具体结构不包含下面哪种(A) A:Windows系统 B:Apache服务器 C:MySQL数 ...

  8. Matlab中double,im2double,mat2gray区别

    转载:http://blog.sina.com.cn/s/blog_6c41e2f30101559d.html ****************假设某图像数据A(uint8格式)*********** ...

  9. 深入理解javascript原型和闭包(3)——prototype原型

    既typeof之后的另一位老朋友! prototype也是我们的老朋友,即使不了解的人,也应该都听过它的大名.如果它还是您的新朋友,我估计您也是javascript的新朋友. 在咱们的第一节(深入理解 ...

  10. tyvj1203 机器分配

    描述 总公司拥有高效生产设备M台,准备分给下属的N个公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M<=100,N& ...