Friday, May 18, 2012

Silverlight : Creating and Using Service Oriented Architecture in Silverlight

Service Oriented Architecture is a methodologies for  development and integration where functionality is grouped  and packaged as interoperable services.

In this post we go through creating custom response and request classes that use to get response from service and convert it to response type.

I have created sample that convert JSON result to DataContract ( passed generic types).
I have used Newtonsoft.Json dll to Deserialize JSON value.

Step 1 : Create Request Class.

 public class MyRequest
 {
    public List<KeyValuePair<string, string>> Parameter { get; set; }
 }

this class used as request for method that have list of  parameters.

Step 2 : Create Class for ResponseType.

 public enum MyResponseType
 {
        SUCCESS,
        ERROR       
 }

Step 3 : Create Class for Response
 
public class MyResponse<T>
{
    public String ResponseType { get; set; }
    public T Data { get; set; }
}

This class will return result of type passed (generic type),
ResponseType parameter will return Success or Error while getting response from service
Data parameter return data converted to passed Type.

Step 4 :Create Service Helper class and into that class Create Method that have Request and Response as a Parameter.
 
public class MyServiceHelper 
{
 
  public string URL { get; set; } 
  public MyServiceHelper(string uri)
  {
    URL=uri; 
  }
  public void CallJSON<T>(string methodName, List<KeyValuePair<string, string>> parameter,
         Action<MyResponse<T>> callbackMethod)
  {
      CallMethod<T>(methodName, parameter, callbackMethod);
  }
 
  public void CallMethod<T>(string methodName, List<KeyValuePair<string, string>> parameter,
          Action<MyResponse<T>> callbackMethod)
  {
      WebClient client = new WebClient();
      client.Headers["contentType"] = "application/json; charset=utf-8";      

      string fullUrl = 
          AppendQueryStringToUrl(URL + methodName, parameter);
      client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_WebRequestCompleted<T>);
      client.OpenReadAsync(new Uri(fullUrl), callbackMethod);
      break;

  }
  void client_WebRequestCompleted<T>(object sender, 
            System.ComponentModel.AsyncCompletedEventArgs e)
  {
     var result = new MyResponse<T>();
     if (e.Error != null)
     {
         result.ResponseType = MyResponseType.ERROR.ToString();             
     }
     else if (e is UploadStringCompletedEventArgs)
     {
         result = JsonConvert.DeserializeObject<MyResponse<T>>(((UploadStringCompletedEventArgs)e).Result);
     }
     else
     {
         StreamReader reader = new StreamReader(((OpenReadCompletedEventArgs)e).Result);
         string strResult = reader.ReadToEnd();
         result = JsonConvert.DeserializeObject<MyResponse<T>>(strResult);
     }
     Action<MyResponse<T>> responseResult= (Action<MyResponse<T>>)e.UserState;
     responseResult(result);
  }
  public string AppendQueryStringToUrl(string url, List<KeyValuePair<string, string>> parameters)
  {
    StringBuilder combinedParams = new StringBuilder();
    if (parameters != null)
    {
       parameters.ForEach((parameter) =>
       {
           combinedParams.AppendFormat("&{0}={1}", parameter.Key, 
                         HttpUtility.UrlEncode(parameter.Value));
       });
       if (combinedParams.Length > 0)
       {
           combinedParams.Replace("&", "?", 0, 1);
       }
    }
    return url + combinedParams.ToString();
  } 
} 

As shown in above code, first i have created CallJSON method that contains methodname, list of paramters and callback response that targeted to Action result.

In CallMethod<T> method, i have created object WebClient class.
WebClient is used to call service Url with querystring parameter and it has Header contenttype.
Header ContentType carry content type info that specify which type of result are you getting from service.

In client_WebRequestCompletedMethod<T> we are getting response of JSON string.

Now we have to Deserialize JSON value to Type of <T> generic class provided in response type.

Step 5 : Create Generic Class for result

   [DataContract]
    public class Employee
    {
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public string LastName { get; set; }
        [DataMember]
    }

Step 6 : Call ServiceHelper Method to Get Response

 private void GetSiteDownInfoList()
 {            
     List<Employee> empList=new List<Employee>();
     MyServiceHelper service = new MyServiceHelper("http://localhost/EmployeeService");
     List<KeyValuePair<string, string>> data = new List<KeyValuePair<string, string>>();
     data.Add(new KeyValuePair<string, string>("userid", "1"));
 
     service.CallJSON<List<Employee>>("GetEmployees", data, (response) =>
     {
         if (response.ResponseType.ToString().Equals(MyResponseType.SUCCESS.ToString()))
         {
             response.Data.ForEach(t => empList.Add(t));
         }

     });
           
  }

So, this way you can create your own reusable class for your application.
 

No comments:

Post a Comment