Through the introduction of the previous article, we know that all the functions of WCF related to encoding and decoding are implemented in the corresponding System.Xml.XmlDictionaryWriter and System.Xml.XmlDictionaryReader. But in the true WCF processing framework, the Xmldictioanrywriter and XmlDictionaryReader objects are not used directly, and the corresponding message encoder (System.ServiceModel.Channels.MessageEncoder) for its further encapsulation, specifically for message encoding and decoding.
First, Message encoder (Messageencoder)
The message encoder is represented by the type Messageencoder, Messageencoder is an abstract class defined under the System.ServiceModel.Channels namespace. As can be seen from the definition below, Messageencoder mainly consists of two types of operations: reading messages and writing messages, respectively, through the Readermessage and Writemessage methods. In addition, two additional methods,getproperty<t> are used to get some properties related to Messageencoder, Iscontenttypesupported is used to determine whether Messageencoder supports some type of MIME type.
1:public Abstract class Messageencoder
2: {
3://other Members
4:public virtual T getproperty<t> () where t:class;
5:public virtual bool Iscontenttypesupported (string contentType);
6:
7:public message readmessage (arraysegment<byte> buffer, BufferManager BufferManager);
8:public message Readmessage (stream stream, int maxsizeofheaders);
9:public Abstract Message Readmessage (arraysegment<byte> buffer, BufferManager BufferManager, String Contenttyp e);
10:public Abstract message Readmessage (stream stream, int maxsizeofheaders, string contentType);
11:
12:public abstract void writemessage (message message, stream stream);
13:public arraysegment<byte> writemessage (Message message, int maxmessagesize, BufferManager buffermanager);
14:public abstract arraysegment<byte> writemessage (Message message, int maxmessagesize, BufferManager Bufferman ager, int messageoffset);
15:
16:public Abstract string ContentType {get;}
17:public Abstract string mediatype {get;}
18:public Abstract messageversion messageversion {get;}
19:}
In contrast to the 3 types of xmldictionarywriter/xmldictionaryreader described above, WCF also defines Messageencoder:textmessageencoder, Binarymessageencoder and Mtommessageencoder have three messageencoder, which encapsulate Xmlutf8textwriter/xmlutf8textreader, Xmlbinarywriter/xmlbinaryreader and Xmlmtomwriter/xmlmtomreader. WCF defines 3 corresponding factory classes: Textmessageencoderfactory, Binarymessageencoderfactory and mtommessageencoderfactory are used to create the corresponding messageencoder. They collectively inherit an abstract class: System.ServiceModel.Channels.MessageEncoderFactory. The corresponding Messageencoder is obtained by encoder the read-only property.
1:public Abstract class Messageencoderfactory
2: {
3: //other Members
4: Public abstract Messageencoder encoder {get;}
5:}
Second, the example demonstrates that the message is encoded by Messagecoder
Next, we'll show you an example of how to encode a specific message object by Messagecoder. This example mainly demonstrates the comparison between Textmessagecoder and Mtommessageencoder encoding methods. In addition, in order to demonstrate Mtom coding optimization for binary data, we create a message object based on binary content and use a bitmap as the body of the messages.
We first create the following static helper method Writemessage, which writes the message object to a file through the Messageencoderfactory Messageencoder object.
1:static void Writemessage (messageencoderfactory encoderfactory, Message message, string fileName)
2: {
3: using (FileStream stream = new FileStream (FileName, FileMode.Create, FileAccess.Write, Fileshare.write))
4: {
5: encoderFactory.Encoder.WriteMessage (message, stream);
6: }
7:}
If you call the above method, you first need to create the Messageencoderfactory object. Since Textmessageencoderfactory and mtommessageencoderfactory are an internal type and cannot be instantiated directly, only two messageencoder can be created through the mechanism of reflection. The following is the definition of the Textmessageencoder and Mtommessageencoderfactory constructors.
1:internal class Textmessageencoderfactory:messageencoderfactory
2: {
3: //other Members
4: Public textmessageencoderfactory (messageversion version, Encoding writeencoding, int maxreadpoolsize, int Maxwritepoolsize, XmlDictionaryReaderQuotas quotas);
5:}
6:internal class Mtommessageencoderfactory:messageencoderfactory
7: {
8: //other Members
9: Public mtommessageencoderfactory (messageversion version, Encoding writeencoding, int maxreadpoolsize, int maxwritepoolsize, int maxbuffersize, xmldictionaryreaderquotas quotas);
10:}
In the following code, the Message object is created first by the static method CreateMessage of the message, and the 3rd parameter to note is a Bitmap object that represents the bitmap. The Textmessageencoderfactory and Mtommessageencoderfactory objects are then created by reflection, and the helper method defined above is invoked writemessage.
1:message message = Message.createmessage (Messageversion.default, "Http://www.artech.com/myaction", New Bitmap (@ "C:\ Users\jinnan\pictures\photo.jpg "));
2:messagebuffer buffer = message. Createbufferedcopy (int. MaxValue);
3:
4://Create textmessageencoderfactory by reflection
5:string Encoderfactorytype = "System.servicemodel.channels.textmessageencoderfactory,system.servicemodel, Version =3.0.0.0, Culture=neutral, publickeytoken=b77a5c561934e089 ";
6:messageencoderfactory encoderfactory = (messageencoderfactory) activator.createinstance (Type.GetType ( Encoderfactorytype), Messageversion.default, Encoding.UTF8, Int. MaxValue, Int. MaxValue, New XmlDictionaryReaderQuotas ());
7:
8:writemessage (encoderfactory, buffer. CreateMessage (), @ "E:\message.text.xml");
9:
10://Create mtommessageencoderfactory by reflection
11:encoderfactorytype = "System.servicemodel.channels.mtommessageencoderfactory,system.servicemodel, Version= 3.0.0.0, Culture=neutral, publickeytoken=b77a5c561934e089 ";
12:encoderfactory = (messageencoderfactory) activator.createinstance (Type.GetType (Encoderfactorytype), Messageversion.default, Encoding.UTF8, Int. MaxValue, Int. MaxValue, Int. MaxValue, New XmlDictionaryReaderQuotas ());
13:
14:writemessage (encoderfactory, buffer. CreateMessage (), @ "E:\message.mtom.xml");