Update: Mahesh wrote a detailed step-by-step walkthrough of how he built the Ebay POX Proxy Example.

This post discusses the design of a POX Proxy prototype.

Current POX/JSON Support

SL 2 Beta 1 comes with support for consuming POX/JSON services.

The user experience is manual: the client has to use WebClient or HttpWebRequest (see How to: Make Requests to HTTP-Based Services) and then parse the response differently, depending on whether it contains XML or JSON.

XML can be deserialized in three different ways (see Working with XML Data in Silverlight), with XmlSerializer being the strongly-typed deserialization option. JSON can only be deserialized using DataContractJsonSerializer (see Working with JSON Data in Silverlight), which is also strongly-typed.

The code would look something like this (assuming we're working with XML, and the User type has already been defined so that XmlSerilalizer can deserialize the XML returned into it).

public void HowToMakeRequestsToHttpBasedServices()
{

     Uri serviceUri = new Uri("http://fabrikam.com/service/getUser");

     // Append any parameters to serviceUri, if necessary

     HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceUri);
     request.BeginGetResponse(
new AsyncCallback(responseHandler), request);

}

void responseHandler(IAsyncResult asyncResult)
{

     HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
    
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);

     Stream responseStream = response.GetResponseStream();
    
XmlSerializer serializer = new XmlSerializer(typeof(User));

     User user = (User)serializer.Deserialize(responseStream);

     // Use user instance...

}

POX Proxy Prototype

Mahesh prototyped a POX Proxy (available here), which creates a very clean object model to access both POX and JSON, and hides some of the implementation details the current solution relies on.

private void TestPoxProxy()
{

     // Instantiate POX proxy with base service address
    
POXProxyRequest request = new POXProxyRequest(new Uri("http://fabrikam.com/service/"));

     // Set HTTP request verb
    
request.WebMethod = "POST";

     // Use RelativeUri to specify operation on service. This allows
     // us 
to reuse the same proxy instance to call different
     // operations on 
the service
    
request.RelativeUri = new Uri("getUser", UriKind.Relative);

     // Use Dictionary<string, string> QueryParameters to pass any
     // parameters to service
    
request.QueryParameters["apiKey"] = "123456";

     // Specify if you are sending XML ("text/xml") or JSON
     // ("application/json")
    
request.ContentType = "text/xml";

     // Now prepare the body of the request (using strongly-typed
     // model) by setting
properties on an object. See the note at
     // the end about where GetUserRequestType
comes from.
    
GetUserRequestType requestBody = new GetUserRequestType();
     requestBody.UserId = 1;

     // Send request
    
request.GetResponseCompleted += new EventHandler<GetResponseCompletedEventArgs>(responseHandler);
     request.GetResponseAsync<GetUserRequestType>(requestBody);

     // request.RequestSerialized and request.ResponseDeSerialized
     // events 
are available for access to serialized object
     // representations

}

void responseHandler(object sender, GetResponseCompletedEventArgs e)
{

     POXProxyResponse response = e.Response;

     // Get the data from the response, again using strongly-typed
     // object. Note that
this could have been deserialized from either
     // JSON or XML - the proxy 
automatically decides which serializer
     // to use based on the content-type 
of the HTTP response. See the
     //
note at the end about where GetUserResponseType comes from.
    
GetUserResponseType
responseBody = response.GetResponse<GetUserResponseType>();

     // Use the response: responseBody.Name, responseBody.Age, etc..

}

Note: The two types GetUserRequestType and GetUserResponseType are generated and decorated with the appropriate attributes so that they will serialize into the XML/JSON request/response the service expects. If the schema of the request/response is known, these can be auto-generated by a tool. We'll save this discussion for another post.

Ebay POX Proxy Example

Mahesh builds a cool app on top of the POX proxy. The app displays the XML/JSON request and response on the right, and a visualization of the returned data on the left.

POX Proxy Sample

Any comments or thoughts on this design?

Yavor Georgiev
Program Manager
Connected Framework Team