WCF消息之XmlDictionaryWriter
XmlDictionaryWriter,是一个抽象类,从该类中派生了WCF,以便执行序列化和反序列化。
它有4种格式书写器:
CreateBinaryWriter,用于创建写入WCF二进制xml格式的实例
CreateMtomWriter,用于创建以MTOM格式mxl的实例
CreateTextWriter,用于创建写入文本xml的实例
(一)CreateTextWriter
以文本格式写入xml,工厂方法有3个重载:
CreateTextWriter(Stream)
CreateTextWriter(Stream, Encoding)
CreateTextWriter(Stream, Encoding, Boolean)
其中第三个方法中的bool参数用于指定流操作:如果为 true,则完成时编写器关闭流;否则为 false。而字符编码Encoding默认的是utf-8。且只支持utf-8,或unicode大头或小头三种编码。
unicode大头小头就是:Big-Endian,Little-Endian(直译过来就是大头结尾,小头结尾)。其中big-endian是在低地址放高位字节,另一个则相反。例如:0x12345678这个16进制的数字
big-endian
低地址——高地址
12|34|56|78
Little-endian
低地址——高地址
78|56|34|12
(说实在的,big-endian更符合人们的习惯)
例如:“赵”字的unicode的big-endian(可以在记事本中写个赵字,然后保存时编码选择big-的,然后在ultra中打开,看它的16进制编码),只看它的BOM部分就知道了:FE FF
在程序中这个编码可以由Encoding的属性来设置:Encoding.BigEndianUnicode
public void TestTextWriter()
{
MemoryStream ms = new MemoryStream();
using (XmlDictionaryWriter writer =
XmlDictionaryWriter.CreateTextWriter(ms,
Encoding.BigEndianUnicode, false))
{
writer.WriteStartDocument();
writer.WriteElementString("UserName", "Songjiang");
writer.Flush();
}
byte[] bb = ms.ToArray();
Console.WriteLine(BitConverter.ToString(bb));
ms.Position=0;
Console.WriteLine(new StreamReader(ms).ReadToEnd());
ms.Close();
}
这里的工厂方法的第三个参数指定为了false,设置在完成wirter的关闭后,不自动关闭对应流,因为后边还要用到这个流。用完后再显示关闭可以了。
它的输出为:
FE-FF-00-3C-00-3F-00-78-00-6D-00-6C-00-20-00-76-00-65-00-72-00-73-00-69-00-6F-00-6E-00-3D-00-22-00-31-00-2E-00-30-00-22-00-20-00-65-00-6E-00-63-00-6F-00-64-00-69-00-6E-00-67-00-3D-00-22-00-75-00-74-00-66-00-2D-00-31-00-36-00-42-00-45-00-22-00-3F-00-3E-00-3C-00-55-00-73-00-65-00-72-00-4E-00-61-00-6D-00-65-00-3E-00-53-00-6F-00-6E-00-67-00-6A-00-69-00-61-00-6E-00-67-00-3C-00-2F-00-55-00-73-00-65-00-72-00-4E-00-61-00-6D-00-65-00-3E
<?xml version="1.0" encoding="utf-16BE"?><UserName>Songjiang</UserName>
字符编码可以在流字节和xml看出来:FEFF的BOM,和encoding=”utf-16be”
再看看utf-8编码下的情况(只在CreateTextWriter方法中将编码改为utf-8即可):
3C-3F-78-6D-6C-20-76-65-72-73-69-6F-6E-3D-22-31-2E-30-22-20-65-6E-63-6F-64-69-6E-67-3D-22-75-74-66-2D-38-22-3F-3E-3C-55-73-65-72-4E-61-6D-65-3E-53-6F-6E-67-6A-69-61-6E-67-3C-2F-55-73-65-72-4E-61-6D-65-3E
<?xml version="1.0" encoding="utf-8"?><UserName>Songjiang</UserName>
Utf-8的BOM是EF BB BF,但这里的字节却没有。可见,对于Text wirter来说,utf-8编码下,utf-8的BOM是省略的,在组包过程中,这点要注意。
(二)CreateBinaryWriter
以MTOM格式写入xml,工厂方法有2个重载:
CreateMtomWriter(Stream, Encoding, Int32, String)
CreateMtomWriter(Stream, Encoding, Int32, String, String, String, Boolean, Boolean)
这里说一下第一个方法:
前2个参数不用说,一个管流,一个管字符编码。然后是int参数,用于设置缓冲的最大字节数,第4个字串型用于设置soap头中的ContentType属性。(ContentType用于描述内容类型的字符串,格式通常为:类型/字类型,其中类型为常规内容范畴,而子类为特定内容类型。对于这个,可以网上找下,例如:text/html)
public void TestMTOMWriter()
{
MemoryStream ms = new MemoryStream();
XmlDictionaryWriter _writer =
XmlDictionaryWriter.CreateMtomWriter(ms,
Encoding.UTF8, 1000, "Application/soap+xml");
_writer.WriteStartDocument();
_writer.WriteElementString("UserName", "Songjiang");
_writer.Flush();
byte[] bb = ms.ToArray();
Console.WriteLine(BitConverter.ToString(bb));
StreamReader sr = new StreamReader(ms);
ms.Position = 0;
string sx = sr.ReadToEnd();
Console.WriteLine(sx);
ms.Close();
sr.Close();
}
结果:
4D-49-4D-45-2D-56-65-72-73-69-6F-6E-3A-20-31-2E-30-0D-0A-43……省略
MIME-Version: 1.0
Content-Type: multipart/related;type="application/xop+xml";
boundary="551a8456-58c9-46ff-b481-f81747b71098+id=1";
start="<http://tempuri.org/0/634052866078593750>";
start-info="Application/soap+xml"
--551a8456-58c9-46ff-b481-f81747b71098+id=1
Content-ID: <http://tempuri.org/0/634052866078593750>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="Application/soap+xml"
<?xml version="1.0" encoding="utf-8"?><UserName>Songjiang</UserName>
--551a8456-58c9-46ff-b481-f81747b71098+id=1--
看第二个方法:
CreateMtomWriter(Stream, Encoding, Int32, String, String, String, Boolean, Boolean)
前4个参数已经说过,
Stream stream,
Encoding encoding,
int maxSizeInBytes,
string startInfo,
string boundary,
string startUri,
bool writeMessageHeaders,
bool ownsStream
现在说后4个,从字面上可以看出,第5个用于设置MIME边界字串,第6个用于设置MIME部分的ID uri,第7个用于设置是否写入消息头,最后一个用于设置在完成writer的关闭时,是否关联关闭对应流。也写一个例子:
XmlDictionaryWriter _writer = XmlDictionaryWriter.
CreateMtomWriter(ms, Encoding.UTF8, 1000, "Application/soap+xml"
,"thisisBoundary============","startUri===1234567890",true,false);
MIME-Version: 1.0
Content-Type: multipart/related;type="application/xop+xml";
boundary="thisisBoundary============";
start="<startUri===1234567890>";
start-info="Application/soap+xml"
--thisisBoundary============
Content-ID: <startUri===1234567890>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="Application/soap+xml"
<?xml version="1.0" encoding="utf-8"?><UserName>Songjiang</UserName>
--thisisBoundary============--
其中,黑体部分标出了边界和起始标识串的位置,而斜体字部分就是消息头,这部分由这个方法的第7个布尔参数来控制。(对于边界,它以一行开始,且前2个字符为--,而总边界结束也由—结尾,还要注意起始头添加了一对尖括号,这些内容可以查阅相关文档)
对于soap中的MIME附件,这个方法可以很好的实现。
(三)CreateMtomWriter
以二进制写入xml
它有4个重载方法:
CreateBinaryWriter(Stream)
CreateBinaryWriter(Stream, IXmlDictionary)
CreateBinaryWriter(Stream, IXmlDictionary, XmlBinaryWriterSession)
CreateBinaryWriter(Stream, IXmlDictionary, XmlBinaryWriterSession, Boolean)
它的参数为:
Stream stream,
IXmlDictionary dictionary,
XmlBinaryWriterSession session,
bool ownsStream
其中,第一个与第四个就不说了,第二个表示用于压缩的XmlDictionary对象,如果不压缩则写null,第三个用于允许发送者和接收者自动创建和协调一个动态的XmlDictionary
public void TestBinaryWriter()
{
MemoryStream ms = new MemoryStream();
XmlDictionaryWriter _writer =
XmlDictionaryWriter.CreateBinaryWriter(ms, null,null);
_writer.WriteStartDocument();
_writer.WriteElementString("UserName", "Songjiang");
_writer.Flush();
byte[] bb = ms.ToArray();
Console.WriteLine(BitConverter.ToString(bb));
StreamReader sr = new StreamReader(ms);
ms.Position = 0;
string sx = sr.ReadToEnd();
Console.WriteLine(sx);
_writer.Close();
ms.Close();
sr.Close();
}
结果:
40-08-55-73-65-72-4E-61-6D-65-99-09-53-6F-6E-67-6A-69-61-6E-67
@€serName� Songjiang
更多详细内容请见:
http://www.cnblogs.com/frank_xl/archive/2009/12/01/1614830.html
WCF消息之XmlDictionaryWriter的更多相关文章
- WCF初探-4:WCF消息交换模式之请求与答复模式
请求与答复模式( Request/Reply) 这种交换模式是使用最多的一中,它有如下特征: 调用服务方法后需要等待服务的消息返回,即便该方法返回 void 类型 相比Duplex来讲,这种模式强调的 ...
- WCF初探-19:WCF消息协定
WCF消息协定概述 在生成 WCF应用程序时,开发人员通常会密切关注数据结构和序列化问题,而不必关心携带数据的消息结构. 对于这些应用程序,为参数或返回值创建数据协定的过程很简单.但是,有时完全控制 ...
- 替换 wcf 消息传输中的 命名空间
替换 wcf 消息传输中的 命名空间,http://vanacosmin.ro/Articles/Read/WCFEnvelopeNamespacePrefix
- WCF消息交换模式之双工通讯(Duplex)
WCF消息交换模式之双工通讯(Duplex) 双工通讯Duplex具有以下特点: 1它可以在处理完请求之后,通过请求客户端中的回调进行响应操作 2.消息交换过程中,服务端和客户端角色会发生调换 3.服 ...
- Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token
原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf? 因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...
- WCF 消息压缩性能问题及解决方法
最近使用WCF作为通迅框架开发一套信息系统,系统使用传统C/S框架,系统有可能会部署在互联网上,因此决定对传输的数据进行GZIP压缩,原来在使用.NET Remoting时,可以使用插入自定义的Cha ...
- WCF - 消息
SOAP SOAP是Simple Object Access Protocol(简单对象访问协议)的简称 而如今SOAP已经成为了符合W3C制定的SOAP规范的消息 允许您使用 XML 在通过低层 I ...
- WCF初探-3:WCF消息交换模式之单向模式
单向模式(One-Way Calls): 在这种交换模式中,存在着如下的特征: 只有客户端发起请求,服务端并不会对请求进行回复 不能包含ref或者out类型的参数 没有返回值,返回类型只能为void ...
- WCF初探-5:WCF消息交换模式之双工通讯(Duplex)
双工通讯Duplex具有以下特点: 1它可以在处理完请求之后,通过请求客户端中的回调进行响应操作 2.消息交换过程中,服务端和客户端角色会发生调换 3.服务端处理完请求后,返回给客户端的不是reply ...
随机推荐
- Mahout机器学习平台之聚类算法具体剖析(含实例分析)
第一部分: 学习Mahout必需要知道的资料查找技能: 学会查官方帮助文档: 解压用于安装文件(mahout-distribution-0.6.tar.gz),找到例如以下位置.我将该文件解压到win ...
- js 验证手机号 以及身份证正则表达式
手机号:① /^1(3[0-9]{9}|5[0-35-9][0-9]{8}|7[07][0-9]{8}|8[25-9][0-9]{8})$/ ② /^1(3\d|5[0-35-9]|7[07]|8[2 ...
- java实现随机验证码的图片
链接地址:http://blog.sina.com.cn/s/blog_407a68fc010006qo.html 1.一共需要2个常用java文件(RandomCode.java和RandomCod ...
- javascript学习(10)——[知识储备]链式调用
上次我们简单的说了下单例的用法,这个也是在我们java中比较常见的设计模式. 今天简单说下链式调用,可能有很多人并没有听过链式调用,但是其实只要我简单的说下的话,你肯定基本上都在用,大家熟知的jQue ...
- Python之路Day10
本节主要内容:memcache&redis.RabbitMQ.twisted框架 1. memcache&redis 1.1 memcache Memcached 是一个高性能的分布式 ...
- poj2947
高斯消元法模版题,但套模版没用.. 先回顾一下线性代数的知识. 若要求解如下方程: 首先,其系数矩阵为 然后,其增广矩阵为: 然后若要求解这个方程,首先将第一行第一个元素化为1,即:第一行乘以1/3. ...
- 鹅厂揭秘——高端大气的App电量測试
怎样评价我们开发出来的应用是耗电还是不耗电,怎样測试?这就是我们今天讨论的主题--电量測试,一个在移动应用中新出现的測试类型. 作者简单介绍 watermark/2/text/aHR0cDovL2Js ...
- python2.7 串口操作方式 编译 .py为windows可运行exe文件
一 python操作串口 首先下载安装串口模块pyserial . 代码实现: import serial ser = serial.Serial('/dev/ttyUSB2', 115200) pr ...
- SQL__用命令删除定期的备份数据库文件
用计划任务可以定期执行下列语句: FORFILES /P e:\test /M *.bak /C "cmd /C del /Q @path" /d -4 其中可更换目录与文件类型. ...
- 以libevent网络库为引:网络通信和多线程
1. windows下编译及使用libevent http://www.cnblogs.com/luxiaoxun/p/3603399.html 2. <<libevent学习资料&g ...