zoukankan      html  css  js  c++  java
  • 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-EndianLittle-Endian(直译过来就是大头结尾,小头结尾)。其中big-endian是在低地址放高位字节,另一个则相反。例如:0x12345678这个16进制的数字

    big-endian

    低地址——高地址

    12345678

     

    Little-endian

    低地址——高地址

    78|56|34|12

    (说实在的,big-endian更符合人们的习惯)

    例如:字的unicodebig-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看出来:FEFFBOM,和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-8BOMEF BB BF,但这里的字节却没有。可见,对于Text wirter来说,utf-8编码下,utf-8BOM是省略的,在组包过程中,这点要注意。

     

    (二)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

    博客园大道至简

    http://www.cnblogs.com/jams742003/

    转载请注明:博客园

  • 相关阅读:
    网页端打开手机上的app
    iOS 9学习系列:打通 iOS 9 的通用链接(Universal Links)
    自定义 URL Scheme 完全指南
    App开发流程之加密工具类
    iOS8系统H264视频硬件编解码说明
    人脸识别
    app上线具体流程
    第三方分享
    Android摸索-二、解决Android SDK Manager下载太慢问题
    Android摸索一环境搭建
  • 原文地址:https://www.cnblogs.com/jams742003/p/1698277.html
Copyright © 2011-2022 走看看