Friday, November 4, 2011

.NET Client to invoke a REST Service

To access a REST Service you can use the below code:


using System.Net;
using System.IO;
 
public string UseHttpWebApproach<T>(string serviceUrl, string resourceUrl, string method, T requestBody)
{
    string responseMessage = null;
    var request = WebRequest.Create(string.Concat(serviceUrl, resourceUrl)) as HttpWebRequest;
    if (request != null)
    {
        request.ContentType = "text/xml";
        request.Method = method;
    }
 
    if(method == "POST" && requestBody != null)
    {
        // NOTE: The below can be used when you want to serialize the request using XmlSerializer
 
        //byte[] requestBodyBytes = ToByteArrayUsingXmlSer(requestBody, "http://schemas.datacontract.org/2004/07/XMLService");
 
        // NOTE: The below code is used as we are serializing the request using DataContractSerializer
 
        byte[] requestBodyBytes = ToByteArrayUsingDataContractSer(requestBody);
        request.ContentLength = requestBodyBytes.Length;
        using (Stream postStream = request.GetRequestStream())
            postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);
    }
 
    if (request != null)
    {
        var response = request.GetResponse() as HttpWebResponse;
        if(response.StatusCode == HttpStatusCode.OK)
        {
            Stream responseStream = response.GetResponseStream();
            if (responseStream != null)
            {
                var reader = new StreamReader(responseStream);
                responseMessage = reader.ReadToEnd();
            }
        }
        else
        {
            responseMessage = response.StatusDescription;
        }
    }
    return responseMessage;
}
 
private static byte[] ToByteArrayUsingDataContractSer<T>(T requestBody)
{
    byte[] bytes = null;
    var serializer1 = new DataContractSerializer(typeof(T));
    var ms1 = new MemoryStream();
    serializer1.WriteObject(ms1, requestBody);
    ms1.Position = 0;
    var reader = new StreamReader(ms1);
    bytes = ms1.ToArray();
    return bytes;
}
 
private static byte[] ToByteArrayUsingXmlSer<T>(T requestBody, string xmlNamespace)
{
    byte[] bytes; 
    using (var s = new MemoryStream())
    {
        var serializer = new XmlSerializer(typeof(T), xmlNamespace);
        serializer.Serialize(s, requestBody);
        bytes = s.ToArray();
    }
    return bytes;
}


Using 3rd party library such as RestSharp the client code is as shown below:


private string UseRestSharpApproach(string serviceBaseUrl, string resourceUrl, Method method, object requestBody)
{
    var client = new RestClient();
    client.BaseUrl = serviceBaseUrl;
    var request = new RestRequest(method) {DateFormat = DataFormat.Xml.ToString(), Resource = resourceUrl};
    request.AddParameter("text/xml", requestBody, ParameterType.RequestBody);
    //request.AddParameter("xmlString", HttpUtility.HtmlEncode(requestBody));
    var response = client.Execute(request);
    string responseString;
    if (response.StatusCode == HttpStatusCode.OK)
    {
        responseString = HttpUtility.HtmlDecode(response.Content);
    }
    else
    {
        responseString = response.StatusDescription + " --------------------" + HttpUtility.HtmlDecode(response.Content);
    }
    return responseString;
}

The possible values for parameters are :
  1. ServiceUrl : http://localhost/RestSample/RestService.svc
  2. ResourceUrl:
      • GetDataFromStringAsString
      • GetDataUsingDataContract
      • GetDataFromString
  3. Various types of RequestBody are shown below:


    • <?xml version=""1.0""?><product id='1'>
          <name>Bread</name>
          <price unit='un'>2.50</price>
      </product>

      CompositeType objComposite = new CompositeType();
      objComposite.BoolValue = true;
      objComposite.StringValue = "Hello World";

      <SampleItem xmlns="http://schemas.datacontract.org/2004/07/XMLService"  xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
          <Id>7</Id>
          <StringValue>Hello World</StringValue>
      </SampleItem>

One thing to note when using RestSharp library and you want to pass a simple string such as "Hello World" to the REST Service should be sent as shown below:


<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/"> Hello World</string>

The response from a REST Service is always mapped to a HTTP status codes such as 200, 400, 500, 404

For a list of status code and what they mean you can find them here.

If you want to know the exact error on what the error was you can enable tracing on your Services. You can do that as i explained in my previous blog here 

No comments: