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相关推荐

  1. 替换 wcf 消息传输中的 命名空间

    替换 wcf 消息传输中的 命名空间,http://vanacosmin.ro/Articles/Read/WCFEnvelopeNamespacePrefix 转载于:https://www.cnb ...

  2. WCF消息拦截,利用消息拦截做身份验证服务

    本文参考  http://blog.csdn.net/tcjiaan/article/details/8274493  博客而写 添加对信息处理的类 /// <summary>/// 消息 ...

  3. WCF分布式安全开发实践(9):消息安全模式之Windows身份验证:Message_Windows_NetTcpBinding...

    今天继续WCF分布式安全开发实践(9):消息安全模式之Windows身份验证:Message_Windows_NetTcpBinding.本文介绍的内容主要是:主要是消息安全模式的Windows身份验 ...

  4. 扩展WCF的消息分发行为

    使用消息分发检查器IDispatchMessageInspector.服务器行为IServiceBehavior.端点行为IEndpointBehavior扩展WCF的消息分发行为 Extend WC ...

  5. DotNet关键知识点——WCF篇(六)

    关于WCF消息通信的安全性论题. 1. 传输层面的安全性 一般方法: binding单元中加security单元,security一般含mode属性,一般将其设置为"Transport&qu ...

  6. WCF 第四章 绑定 msmqIntegrationBinding

    msmqIntegrationBinding 绑定用来在一个WCF应用程序和一个直接利用MSMQ的应用程序间通信-比如,使用System.Messaging.这允许开发人员利用WCF同时也使 用他们已 ...

  7. WCF服务编程设计规范(6):队列服务、安全和服务总线

    WCF服务编程设计规范(6):队列服务.安全和服务总线.本节整理队列服务(Queue Servuce).服务安全(Service Security)和服务总线(Service Bus)的设计规范. Q ...

  8. WCF Membership Provider

    ASP.NET 是自.NET 1.x 就已经有的技术,利用IIS+ASP.NET 搭建的网站已经有很多.针对IIS+ASP.NET 的网站模型也有很多案例,通过现在的搜索服务我们可以很轻易的获取这些内 ...

  9. WCF系列学习笔记4之绑定详解

    标准绑定 绑定的基本概念:通道模型具有极大的灵活性,可以在协议通道,编码器,传输通道等各个方面进行设置,每次都需要设置一个完整的通道栈是一个较为复杂的事情,从传输协议上看,有HTTP,TCP,UDP, ...

最新文章

  1. CVPR 2021 比CNN和Transformer更好的Backbone?伯克利谷歌提出BoTNet,精度达84.7%
  2. python手机版idle-Python入门 | IDLE的介绍和使用方法
  3. C#学习基本概念之属性使用
  4. datagrid如何获取一行数据中的某个字段值_MySQL 如何查找删除重复行?
  5. 面试中常问的HTTP/1.0状态码
  6. Create new module “HelloWorld” – in Magento
  7. 当systeminfo不能显示系统启动时间了--用命令行修复一下
  8. linux删除文件夹命令6,Linux下创建、删除文件和文件夹命令
  9. html 正方形代码,SVG rect
  10. 上海电信光猫SA1456C桥接后4K IPTV继续使用
  11. 【NOI2015】小园丁与老司机
  12. 【Redis】Redis缓存穿透和雪崩
  13. 黑马程序员JS学习第一天
  14. 字节跳动面试:京东面试真题解析,薪资翻倍
  15. 怎样把多个pdf合并为一份?多个pdf怎么合并成一个pdf?
  16. 图表生成pdf,出坑经历
  17. [Android答答答]Handler是什么?
  18. 【javaEE】网络初识
  19. Java回文数代码(初学者易懂)
  20. android11 Launcher3 桌面定制开发之删除默认Google搜索框

热门文章

  1. 17_android下xmlpull解析
  2. 导入导出oracle数据库表的dmp文件
  3. 使用完成端口监控文件目录的例子
  4. poj 1067 取石子游戏(博弈+威佐夫博奕(Wythoff Game))
  5. javascript 正则表达式-零宽断言
  6. 兼容IE和FF的JS HTMLEncode和HTMLDecode的完整实例[转]
  7. JSON解析的几种方式
  8. Android—AspectJ实践
  9. Java—JVM加载机制
  10. IOS15一个工作空间创建多个项目