拿微信消息返回的示例数据实验
  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. Chrome-Console( Command Line API Reference)

    来源于:https://developers.google.com/web/tools/chrome-devtools/console/command-line-reference The Comma ...

  2. 动态树之LCT(link-cut tree)讲解

    动态树是一类要求维护森林的连通性的题的总称,这类问题要求维护某个点到根的某些数据,支持树的切分,合并,以及对子树的某些操作.其中解决这一问题的某些简化版(不包括对子树的操作)的基础数据结构就是LCT( ...

  3. hihoCoder 后缀数组 重复旋律

    #1403 : 后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成 ...

  4. Ubuntu操作系统相关

    1.安装 三种网络类型 修改密码 重启unbuntu系统,出现starting启动界面后,长按shift键. 出现如下引导界面: (注意:这里保持默认的选项就行,即白色横条选择在*Ubuntu上,不要 ...

  5. [C#] 图文解说调用WebServer实例

    本文旨在实现如何在.NET环境下调用WebServer,以天气接口为例进行说明. WebServer地址:http://www.webxml.com.cn/WebServices/WeatherWeb ...

  6. hdu2929 Bigger Is Better

    题意 给出n根木棍,要你拼一个最大的数,并且这个数是m的倍数. 题解 显然越长的数越大.设\(dp[i][j]\)表示用i根木棍并且\(mod m = j\)的最大长度. 我们很容易想出dp方程,再用 ...

  7. Angular.js实现折叠按钮的经典指令.

    var expanderModule=angular.module('expanderModule',[]) expanderModule.directive('expander',function( ...

  8. Google 地图 API V3 使用入门

    Google官方教程: Google 地图 API V3 使用入门 Google 地图 API V3 针对移动设备进行开发 Google 地图 API V3 之事件 Google 地图 API V3 ...

  9. 暴力枚举N级子域名

    #!/usr/bin/env python# -*- encoding: utf-8 -*-# A simple and fast sub domains brute tool for pentest ...

  10. [NHibernate]持久化类(Persistent Classes)

    系列文章 [Nhibernate]体系结构 [NHibernate]ISessionFactory配置 引言 持久化类是应用程序用来解决商业问题的类(比如,在电子交易程序中的Customer和Orde ...