Adding multiple parameters to JSON-enabled WCF service
One thing you’ll be tempted to do when you first start creating web services is to add multiple parameters to your web methods. Don’t, it will soon trip you up, especially if any of those parameters are complex types.
A better way to handle calling WCF web services that return JSON formatted results is to use Request and Response objects. Your WCF service accepts a single complex Request object that contains all the values it needs to perform its job. The results, along with any exceptions and messages are passed back to the caller in the Response object.
In this post, we’ll modify our GetPlaces method to use Request and Response objects instead of querystring parameters.
First add the following PlaceRequest and PlaceResponse classes.
Code Snippet
- public class PlaceRequest
- {
- public string Country { get; set; }
- public int MaxPopulation { get; set; }
- }
Code Snippet
- public class PlaceResponse
- {
- public bool HasError { get; set; }
- public string Status { get; set; }
- public List<Place> Results { get; set; }
- }
Then modify the GetPlace method as follows.
Code Snippet
- [OperationContract]
- [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
- public PlaceResponse GetPlaces(PlaceRequest Request)
- {
- // instantiate our response object
- PlaceResponse response = new PlaceResponse();
-
- // create a list of places
- List<Place> places = new List<Place>();
-
- places.Add(new Place {
- Name = "London",
- Country = "UK",
- Population = 7825200
- });
-
- places.Add(new Place {
- Name = "New York",
- Country = "USA",
- Population = 8175133
- });
-
- places.Add(new Place
- {
- Name = "Los Angeles",
- Country = "USA",
- Population = 3862839
- });
-
- places.Add(new Place {
- Name = "Sydney",
- Country = "Australia",
- Population = 4391674
- });
-
- var results = from p in places
- where p.Country == Request.Country && p.Population < Request.MaxPopulation
- select p;
-
- response.Results = results.ToList();
-
- // return the response
- return response;
- }
You’ll notice that we’ve changed the WebGet tag to WebInvoke. This declaration enables us to use the HTTP POST verb, instead of GET, since the calling function will be sending a complex object in the request body, not just a parameter in the URL.
To test this web service you’ll need to create a POST HTTP request. The easiest way to do this is use a tool such as Fiddler to create the request.
Add Content-Type:application/json to the request header and specify the body as such:
{"Request":{"Country":"USA", "MaxPopulation":"4000000"}}
You’ll notice the values for Country and MaxPopulation are enclosed in an object called Request. This is because the web method parameter is called Request.
If everything goes well, Fiddler will report a response that includes the following JSON.
{"HasError":false,"Results":[{"Country":"USA","Name":"Los Angeles","Population":3862839}],"Status":null}