Internal classes to understand WCF Message: XmlDictionaryWriter Class

XmlDictionaryWriter class is one of the most important classes to work with Message in WCF. This class is inherited form XmlWriter class. Essentially this takes as Stream as input parameter. This class mainly performs serialization and encoding of the stream to send as Message in WCF.

 

 

image

There are four factory methods of this class being used extensively. Each method has their own uses as of requirement.

image

image

CreateDictionaryWriter method

It takes as input parameter object of XmlWriter. This method is not being used very extensively. This method could be very handy when we do not have any choice but XmlWriter object as input parameter.

 

image

If you see below code, we are creating a stream. Using stream we are creating a XmlWriter object and passing to XmlDictionaryWriter to create object of the same.


using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Xml;
using System.Collections.Generic;
using System.IO;
namespace XML
{
    class Program
    {

        static void Main(string[] args)
        {


            MemoryStream stream = new MemoryStream();
            XmlWriter writer = XmlWriter.Create(stream);
            XmlDictionaryWriter dctWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer);
            Console.WriteLine(dctWriter.ToString());
            Console.ReadKey(true);


        }
    }

}


 

CreateTextWriter method

This method helps us to create text encoded XML. This is overloaded with three different types of input set.

It can take only a Stream to write to. It writes output with default encoding UTF8.

 

image

It can as input Stream to write to and character Encoding of the output

 

image

It can take Stream to write, character encoding of output and a Boolean value. If Boolean input is true then Stream is closed by writer once writing is done. Else Stream will not be closed by the writer.

image

CreateTextWriter supports only,

  1. UTF8 Encoding
  2. UTF 16 little endian
  3. UTF16 big endian

 

We have been doing much of technical talk and I am sure you do not like it Smile so to please you let me show you, how we could use CreateTextWriter class.

In below code we are reading stream and writing using CreateTextWriter .

 


using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Xml;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace XML
{
    class Program
    {

        static void Main(string[] args)
        {


            MemoryStream streamToWrite = new MemoryStream();

            using (XmlDictionaryWriter wrt = XmlDictionaryWriter.CreateTextWriter(streamToWrite, Encoding.UTF8, false))
            {
                wrt.WriteStartDocument();
                wrt.WriteElementString("SongName", "urn:Mysong", "F:\\a.wmv");
                wrt.Flush();
            }

            Console.WriteLine("Number Of Bytes wriiten {0} ", streamToWrite.Position);
            Console.ReadKey(true);
            streamToWrite.Position = 0;
            Byte[] bytes = streamToWrite.ToArray();
            Console.WriteLine(bytes.Length);
            Console.ReadKey(true);
            Console.WriteLine(BitConverter.ToString(bytes));
            Console.WriteLine("Data Read from stream : {0}", new StreamReader(streamToWrite).ReadToEnd());
            Console.ReadKey(true);


        }
}
}



On running you will get output as below,

image

If you would have noticed we used empty stream. So as a resultant we are getting 86 bytes written.

CreateMtomWriter method

This method is used to create MTOM-encoded XML.

We can pass Stream to write and other parameters like encoding.

image

This method allows us to pass boundary of MIME type also along with Stream to write.

image

We are just modifying the write method in above code and you can see the change in output behavior as below,



using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Xml;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace XML
{
    class Program
    {

        static void Main(string[] args)
        {


            MemoryStream streamToWrite = new MemoryStream();


            using (XmlDictionaryWriter wrt = XmlDictionaryWriter.CreateMtomWriter(streamToWrite,
                                                                                  Encoding.UTF8,
                                                                                  1000,
                                                                                  "startinfo",
                                                                                  "Boundary",
                                                                                  "urn:stratUri",
                                                                                  false,
                                                                                  false))
            {
                wrt.WriteStartDocument();
                wrt.WriteElementString("SongName", "urn:Mysong", "F:\\a.wmv");
                wrt.Flush();

            }

            Console.WriteLine("Number Of Bytes wriiten {0} ", streamToWrite.Position);

            streamToWrite.Position = 0;
            Byte[] bytes = streamToWrite.ToArray();


            Console.WriteLine(BitConverter.ToString(bytes));
            Console.WriteLine("Data Read from stream : {0}", new StreamReader(streamToWrite).ReadToEnd());
            Console.ReadKey(true);


        }}}




Expected output you would get as below,

image

I hope this post was useful. I am taking a break here. In next post we will see CreateBinaryWriter method. Thanks for reading Smile

Internal classes to understand WCF Message: XmlDictionary Class

In last post we discussed the way we could create WCF Message. If you go back and reexamine CreateMessage() function , you will find this function is overloaded with 11 different set of inputs.

It is common when you will create Message, you may use XmlDictionary class.

XmlDictionary class allows us to create a private pair of Key and Value. This key-value pair can be used to represent

  • Element name
  • Attribute name
  • XML namespace declaration.

XmlDictionary class uses XmlDictionaryString class object to create key value pair. If you see below code, we are creating a XmlDictionary object and List of XmlDictionaryString.

 

image

dct is object of XmlDictionary and while adding string value in this it returns XmlDictionaryString object.

 


XmlDictionary dct = new XmlDictionary();
            List<XmlDictionaryString> lstData = new List<XmlDictionaryString>();
            lstData.Add(dct.Add("Bat"));
            lstData.Add(dct.Add("Ball"));
            lstData.Add(dct.Add("Wicket"));
            foreach (var r in lstData)
            {
                Console.WriteLine("Key  = {0}  and Value = {1}", r.Key, r.Value);
            }
            Console.ReadKey(true);


 

If you run above code you will get output as below,

image

We are simply adding returned XmlDictionaryString object to list of XmlDictionaryString.

I hope now you have understanding of XmlDictionary class. In next post we will discuss some other important class required to understand Message in WCF.

Thanks for reading  Smile

Create Message in WCF

In last post  we discussed about SOAP Message Versions. Now let us move ahead and create a Message.

image

You can create a Message using CreateMessage() method of Message class . This method is overloaded with 11 different set of input parameters.

Easiest you can create a Message by just providing MessageVersion and action

image

On running above code snippet you will get as message as output and if you notice there is no body in the message since we have not added that.

image

If you want to add a body in the message you can do that but restriction is you can only add serialized object as message body.

Let us add a string to message body. Since string and other built in types are default serialized. So we do not need to explicitly serialize that.

image

 

In above function we have added a string message body with value “HI I am Body “. On running above code snippet you will get output as below,

image

 

Let us create a Message as object of custom class as message body. Assume you have a custom class called Product.

image

And you want to create a Message having instance of this class as message body. You can very much do that as below,

image

On running above code you will get output as below,

image

And you can see the custom object is being part of the Message there.

For your reference code to copy given below Smile

Program.cs

using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Xml;
using System.Collections.Generic;
namespace XML
{
    class Program
    {

        static void Main(string[] args)
        {


            Message msg = Message.CreateMessage(MessageVersion.Soap11, "urn:MyAction");
            Console.WriteLine(msg.ToString());
            Console.ReadKey(true);

            msg = Message.CreateMessage(MessageVersion.Soap11WSAddressing10,
                                         "urn:MyAction",
                                         "Hi I am Body");

            Console.WriteLine(msg.ToString());
            Console.ReadKey(true);

            Product p = new Product
            {
                ProductId = 1,
                ProductName = "Books",
                ProductPrice = 110.0
            };
            msg = Message.CreateMessage(MessageVersion.Soap12,
                                        "urn: MY Action",
                                        p);
            Console.WriteLine(msg.ToString());
            Console.ReadKey(true);



        }


    }

    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public double ProductPrice { get; set; }
    }

}


 

Now you know how you could create a Message in WCF. I hope this post was useful. Thanks for Reading

WCF SOAP Message Version

Service and client communicate to each other through Messages. So they must be agreed upon the Message version while communicating. Service may send Message as POX or may be as SOAP12.

When at service side we create a SOAP Message, we term it as Message Object Model. Essentially, we can say Message Object Model is used to create SOAP Message in WCF to communicate with client. When we create SOAP Message, we specify the Message Version and it is not amendable afterwards.

Message created using Message Object Model essentially consists of Envelope versions and Addressing version type.

 

image

 

MessageVersion class is inside System.ServiceModel.Channels. If you navigate to MessageVersion class you would find AddressingVersion and EnvelopeVersion there.

 

image

Different Message versions are as below

image

If you want you can create your own Message Version

image

 

CreateVersion is overloaded function. Either you can pass only Envelope Version or Envelope Version and Addressing Version both to create your own Message Version.

Now let us go ahead and inspect the entire Message version to find what Envelope Version and AddressingVersion type are inside a particular Message Version.

 


using System;
using System.ServiceModel.Channels;
namespace XML
{
    class Program
    {

        static void Main(string[] args)
        {
            MessageVersion version = MessageVersion.Default;
            Display(version ,"Default");
            version = MessageVersion.Soap11 ;
            Display(version,"SOAP11");
            version = MessageVersion.Soap11WSAddressing10 ;
            Display(version,"SOAP1110");
            version = MessageVersion.Soap11WSAddressingAugust2004;
            Display(version,"SOAPAddressingAuguest2004");
            version = MessageVersion.Soap12 ;
            Display(version,"SOAP12");
            version= MessageVersion.Soap12WSAddressing10;
            Display(version,"SOAP1210");
            Console.ReadKey(true);
        }

        static void Display(MessageVersion v , string strName)
        {
            Console.WriteLine(strName);
            Console.WriteLine("Addressing : " + v.Addressing.ToString());
            Console.WriteLine("Envelope : " + v.Envelope.ToString());
            Console.WriteLine();
        }
    }
}


 

If you run above code you will get output as below,

image

If you want to create a new Message Version, you can very much do that.

image

If you want you can pass as input parameter only EnvelopeVersion

image

Note: Display is a function to print EnevelopeVesrion and AddressingVesrion. This function is created previously in above code)

If you run above code you will get output as below

image

I hope now you are having some idea about SOAP Message Version. In next post, we will see more on Message in WCF.

I hope this post was useful. Thanks for reading Smile