|
最近爽哥想尝试下微信公众帐号的开发者模式,他在微信公众平台申请了个帐号.接着就去看开放平台的接口指南,他在群里放了个链接,最近微信实在是被炒的过热,我好奇地也点了进去.
点开消息接口指南,我们可以看到公众平台消息接口是用利用XML进行数据交互的.为了数据操作方便,通常我们会将XML序列化和反序列化. 序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
先说序列化,我们以回复图文消息的XML格式为例,因为这个格式基本上包含了上面消息推送和消息回复的所有了.
- <xml>
- <ToUserName><![CDATA[toUser]]></ToUserName>
- <FromUserName><![CDATA[fromUser]]></FromUserName>
- <CreateTime>12345678</CreateTime>
- <MsgType><![CDATA[news]]></MsgType>
- <ArticleCount>2</ArticleCount>
- <Articles>
- <item>
- <Title><![CDATA[title1]]></Title>
- <Descrip{过滤}tion><![CDATA[descrip{过滤}tion1]]></Descrip{过滤}tion>
- <PicUrl><![CDATA[picurl]]></PicUrl>
- <Url><![CDATA[url]]></Url>
- </item>
- <item>
- <Title><![CDATA[title]]></Title>
- <Descrip{过滤}tion><![CDATA[descrip{过滤}tion]]></Descrip{过滤}tion>
- <PicUrl><![CDATA[picurl]]></PicUrl>
- <Url><![CDATA[url]]></Url>
- </item>
- </Articles>
- <FuncFlag>1</FuncFlag>
- </xml>
复制代码
分析这个格式,我们可以知道他的根的名称为<xml>,其中又包含了<Articles>这个集合的节点,当我们接收到公众平台POST过来的数据响应返回输出时,我们就用到了XML序列化,也就是把响应的数据对象转换为公众平台提供的这种xml数据格式,便于数据的传输. 序列化这里我用c#写了一个简单的示例代码. 为了获取序列化后的字符串,就没有直接输出,当然在你的项目中你可以直接Response.Output.
- /// <summary>
- /// XML序列化
- /// </summary>
- /// <typeparam name="T">对象类型</typeparam>
- /// <param name="t">对象实例</param>
- static string XmlSerialize<T>(T t)
- {
- var serializer = new XmlSerializer(typeof(T));
- var stream = new MemoryStream();
- serializer.Serialize(stream, t);
- return Encoding.UTF8.GetString(stream.GetBuffer());
- //写入文件
- //using (StreamWriter writer = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "weixin.xml"))
- //{
- // serializer.Serialize(writer, t);
- //}
- //直接输出
- //serializer.Serialize(Console.Out, t);
- }
复制代码
这里要提到的是,由于用XmlSerializer类的Serialize方法生成的XML根元素的名称默认为序列化类的名称. 这句话读着怎么特么感觉这么绕口.而我又不想使用xml这么没有意义的字眼作为一个类名,我们需要为序列化类加一个特性标记 [XmlRoot(ElementName = "xml")] 指定生成的 XML 元素的名称为xml.
如果没有添加这个标记,当你的序列化类名和xml的根元素名称不对应的话,总是会爆文档格式错误.
搞定根元素以后,我们就需要解决Articles这个集合节点的问题了,这个时候我们需要新建一个强类型列表,变量名为Articles的公共属性.
- [XmlArrayItem(ElementName = "item")]
- public List<WeixinArticle> Articles { get; set; }
复制代码
XmlArrayItemAttribute是指定 XmlSerializer 可以放置在序列化数组中的派生类型。把类创建完以后,调试看一下,基本上就没有什么大问题了.
再说反序列化.当普通微信用户向公众账号发消息时,微信服务器将POST该消息到填写的URL上.这个时候我们就需要把接收的数据反序列化成我们需要的对象以便于操作存储.这里插一点,通常我们会用Request.Form["param"]来获取Post的数据,而许多开发者在看接口文档时发现POST的数据没有参数,一头雾水,不知道怎么去获取数据了.这里我们通过Request.InputStream来获取传入的 HTTP 实体主体的内容. 详情可参照此篇文章:http://blog.sina.com.cn/s/blog_9fa44b550101ee3r.html
反序列化这里我一样用c#写了一个简单的示例代码.
- /// <summary>
- /// XML反序列化
- /// </summary>
- /// <typeparam name="T">对象类型</typeparam>
- /// <param name="content">内容文本</param>
- /// <returns></returns>
- static T XmlDeserialize<T>(string content)
- {
- var serializer = new XmlSerializer(typeof(T));
- using (var reader = new StringReader(content))
- {
- return (T)serializer.Deserialize(reader);
- }
- }
复制代码
这里因为是直接拷贝回复图文消息的xml示例数据的字符串,就用了Deserialize(TextReader textReader)这个重载,当然你在项目中可以直接用Deserialize(Stream stream)这个重载.
有关xml序列化的问题,可多看看MSDN的这文章XML 和 SOAP 序列化
相关的实例代码文件我已放在github,地址: XmlSerializerExample
匆匆忙忙写完,简单地做个标记.晚上吃饭没吃饱,现在感觉恶心.特么得赶快睡觉了.
如有错误,欢迎指正.
原文链接:
http://imr3.com/tech/weixin-message-api-serialize
|
上一篇:xml反序列化XML 文档(1, 2)中有错误。下一篇:[源码].net/c#微信智能聊天gis位置信息扫一扫获取图片功能
|