Saturday, September 4, 2010

Consuming .Net WCF Rest in different ways

There are different ways to consume wcf rest services in .net, The basic idea is first creating the http request and include the message body and message header. we need to serialize the objects we are going to send, then we need to send the request and then get the response and deserialize to get the response objects.

How to make the request body and how to serialize and deserialize depends on the service method body style that can be Bare or Wrapped, To get some idea about this subject, you can have a look at my post Wrapped BodyStyle in WCF Rest
Please be aware that I am not saying which one is the best way, I am exploring WCF Rest recently and I like to share what I learned with other people. I will be happy to see what other people think.

I am going to show an example:



using System.ServiceModel.Web;
using System.ServiceModel;
using System.Net;
using MyWcfServiceLibrary;
 
namespace MyWcfServiceLibrary
{
    //POCO Entity
    public class Tag
    {
        public int ID { get; set; }
        public string TagName { get; set; }
        public byte Status { get; set; }
    }
 
    [ServiceContract(Namespace = "http://mytagservice")]
    public interface ITagService
    {
        [OperationContract]
        [WebInvoke(Method = "PUT", UriTemplate = "tags/{id}", 
BodyStyle = WebMessageBodyStyle.Bare)]
        int UpdateTag(string id, Tag tag);
    }
 
    public class TagService : ITagService
    {
        public int UpdateTag(string id, Tag tag)
        {
            return 1;
        }
    }
 
 
    //Consuming WCF Rest using WebChanelFactory
    //-----------------------------------------------------------------------
 
    public class Consumer
    {
        private void ConsumeWcfRset1()
        {
            string url = "http://something/MyWebsite/tagservice";
 
            Tag tag1 = new Tag() { ID = 11, TagName = "test", Status = 1 };
            WebChannelFactory<ITagService> cf = new WebChannelFactory<ITagService>(new Uri(url));
            ITagService channel = cf.CreateChannel();
            using (new OperationContextScope(channel as IContextChannel))
            {
                int i = channel.UpdateTag("1", tag1);
            }
        }
 
        //Consuming WCF Rest using HttpWebRequest
        //----------------------------------------
 
        private void ConsumeWcfRest2()
        {
            string url = "http://something/MyWebsite/tagservice";
            Tag tag1 = new Tag() { ID = 11, TagName = "gfgf", Status = 1 };
            HttpWebRequest req = HttpWebRequest.Create(url + "/tags/1") as HttpWebRequest;
            req.Method = "PUT";
            string content = DoSerialize(tag1, "");
            System.Text.UTF8Encoding en = new System.Text.UTF8Encoding();
            byte[] bArray = en.GetBytes(content);
            req.ContentLength = bArray.Length;
            req.ContentType = "text/xml";
            System.IO.Stream requestStream = req.GetRequestStream();
            requestStream.Write(bArray, 0, bArray.Length);
            requestStream.Close();
            HttpWebResponse res = req.GetResponse() as HttpWebResponse;
            System.IO.Stream stream = res.GetResponseStream();
            System.IO.StreamReader sr = new System.IO.StreamReader(stream);
            string str = sr.ReadToEnd();
            sr.Close();
        }
 
        //Consuming WCF Rest using HttpClient(Microsoft.Http in Microsoft WCF Rest Starter Kit)
        //------------------------------------------------------
        private void ConsumeWcfRset3()
        {
            string url = "http://something/MyWebsite/tagservice";
            Tag tag1 = new Tag() { ID = 11, TagName = "gfgf", Status = 1 };
            Microsoft.Http.HttpClient client = new Microsoft.Http.HttpClient();
            string content = DoSerialize(tag1, "");
            Microsoft.Http.HttpContent httpCon = Microsoft.Http.HttpContent.Create(content);
            client.DefaultHeaders.ContentType = "text/xml";
            Microsoft.Http.HttpResponseMessage res = client.Send(Microsoft.Http.HttpMethod.PUT, 
url + "/tags/1", httpCon);
            string str = new System.Text.UTF8Encoding().GetString(res.Content.ReadAsByteArray());
            client.Dispose();
        }
 
 
        private string DoSerialize(object obj, string rootName)
        {
            System.Runtime.Serialization.DataContractSerializer se;
            if (string.IsNullOrEmpty(rootName))
                se = new System.Runtime.Serialization.
DataContractSerializer(obj.GetType());
            else
                se = new System.Runtime.Serialization.
DataContractSerializer(obj.GetType(), rootName, "");
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            se.WriteObject(ms, obj);
            ms.Position = 0;
            byte[] arr = new byte[ms.Length];
            ms.Read(arr, 0, Convert.ToInt32(ms.Length));
            return new System.Text.UTF8Encoding().GetString(arr);
        }
    }
}

Cheers!

kick it on DotNetKicks.com

2 comments:

quentez said...

Very useful, thanks !

lauren said...

People usually get confused when their comes to consume wcf rest services in .net but once the logic and flow becomes clear its so easy to follow.The example you provided here is quite simple to follow and understand so might help many such persons.good Work keep it up!
electronic signatures

Post a Comment