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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在线日志文件丢失的恢复(笔记)
- 下一篇: 迷你世界怎么做娃娃机