WCF Service Contract and XML Serialization

I am building a Service using the WCF REST Starter Kit. This Service contains a method that accepts a complex type as input, it then deserializes the object into it’s concrete type.

Here’s how a service call looks like

using (HttpClient client = new HttpClient()){    RequestObject req = new RequestObject { FirstName = "John", LastName = "Doe", Email="johndoe@somecompany.com"};

    HttpContent body = HttpContentExtensions.CreateXmlSerializable<RequestObject>(req);

    HttpResponseMessage resp = client.Post("http://localhost:1575/Web/Service.svc/SendMail", body);

    Response.Write(resp.Content.ReadAsString());}

What the above does is simply prepare a RequestObject, call a SendMail method on the service using the HttpClient, read and print the response, nothing fancy.

Here’s how the service looks like

[WebHelp(Comment = "Sample description for SendMail")][WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat =WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml,UriTemplate = "SendMail")][OperationContract]public RequestObject SendMail(RequestObject request){    return new RequestObject()    {        FirstName = request.FirstName, LastName = request.LastName,Email = request.Email    }; }

Notice what I’m doing is preparing the same RequestObject and simply pass it as the response.

As you’d expect I’m suppose to get the following response in the browser.

- <RequestObject>  <FirstName>John</FirstName>   <LastName>Doe</LastName>   <Email>johndoe@somecompany.com</Email> </RequestObject>

But the response I receive is similar to this

<RequestObject>    <FirstName i:nil="true" />    <LastNameName i:nil="true" />    <Email>johndoe@somecompany.com</Email></RequestObject>

After a few hours of trying it occurred to me that XML Serialization is done in the alphabetical order if no ordering is specified even if the properties in the class are not in the alpha-order. (arrgh. If only I had used the Paste XML as Type as demo’ed in this screencast by Aaron Skonnard)

So to make it work I had to change the RequestObject class in both places to look like the following.

public class RequestObject{    public string Email { get; set; }    public string FirstName { get; set; }    public string LastName { get; set; }}

Adding Service References and ‘The system cannot find the path specified’ error

I was facing this problem recently in a project when adding a reference to a WCF Service simply gave me this error.

wcferror

I google’d it for a while but in vain, I also removed the auto-gen service entries from the web.config but that did not work either.

Then I realized that earlier I had deleted the Service References folder from the application root, re-add and it worked as expected.

Funny thing is that Visual Studio will not tell you what went wrong, neither folder name appears under Add > ASP.NET Folders nor Visual Studio attempts to recreate it.

Return JSON objects the right way

Today I experienced a weird behavior when I was passing JSON string back to a jQuery call using an Ajax-enabled WCF Service.

My code looked something like this.

[OperationContract, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetJson")]
public string GetJson()
{
    return new JavaScriptSerializer().Serialize(MyCustomObject)
}

The problem with above code is that the string returned is escaped and enclosed with inverted commas that for some reason was not handled properly using jQuery that looked like this.

“[{\"Id\":1,\"SomeKey\":\"SomeMoreText\"}]”

Not sure what I was missing and while there is a JsonResult action in ASP.NET MVC with a .svc there’s nothing that I could use (or may be there is).

To fix it I changed the method like this.

[OperationContract, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetJson")]
public System.IO.Stream GetJson()
{
   byte[] resultBytes = System.Text.Encoding.UTF8.GetBytes(new JavaScriptSerializer().Serialize(MyCustomObject));
   
   WebOperationContext.Current.OutgoingResponse.ContentType = "application/json";
 
   return new MemoryStream(resultBytes); 
}
 

Here’s how Json is returned.

[{"Id":1,"SomeKey":"SomeMoreText"}]

Don’t use UriTemplate = "/MethodName/Param1/{Param1}/Param2/{JsonObject} for Json input with WCF Service

When building Ajax-enabled WCF service that expect a Json object as input then the following would not work

[OperationContract, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/Methodname/jsonvariable/{jsonvariable}/param2/{param2}")]
public void MethodName(string jsonvariable, string param2)
{
 
}

Where jsonvariable is a json object passed through jQuery (or ASP.NET Ajax) to a WCF service that looks like this

[{"Name":"za","Email":zubairdotnet@hotmail.com}]

After spending a while I figured out that the following UriTemplate should be used instead

 

[OperationContract, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/Methodname/?jsonvariable={jsonvariable}&param2={param2}")]
public void MethodName(string jsonvariable, string param2)
{
 
}