Tuesday, July 30, 2013

MVC 4 - WCF - Add Service Reference Generates Blank Proxy

After a long time I created a WCF Service with ws2007HttpBinding which has a complex data model (with inheritance involved). I created the service as usual with the well known configuration and hoping it to work. I just run the application and it ran without any error. Bingo! wow great, I created a service in single go!

Now its time to create a client application. The client I was trying to create is MVC 4 web application (which I am most familiar with). The app was already present and I just need to add a service reference to consume my wcf service. As usual I just right clicked the project, clicked on AddServiceReference, entered the service url, given a friendly name to the service and clicked Ok. Wow! I'm ready with a client for my service. Now its time to call the service method by creating an instance of the client proxy. Being a lazy guy waiting for the visual studio intellisense to show up the given friendly proxy name by typing its initial few letters. Unfortunately, intellisense was not showing anything. OMG! need to wake up now.

Started to trace to identify what went wrong:
            First step I did is checking the proxy code (because I can't relay on intellisense for 100% accuracy. There are times, when everything is fine but intellisense itself is having problems). Well, I did that by clicking on the marked places below:

I noticed that the proxy classes are not generated and the Reference.cs file is blank:

Now my mind also became blank! I was following all the holy steps but still not able to wok as expected. Went back to my WCF application and started to verify following things:
  • Whether all my required data structures are decorated with DataContract (classes) & DataMember (properties) or not.
  • Whether the base class is decorated with DataContract or not. 
  • Whether the KnownTypes are set or not.
Everything was looking fine there but still proxy is not getting created. Frustrating!!!

Decided to check the service with wcftestclient (vs command prompt -> wcftestclient -> Right click & click on Add Service -> Enter service url -> ok) tool. 

Wow, great! it works here. Then, what might be the problem with my MVC 4 application. Just got another thought. Created a new console application and added the service reference in the same was as I did in MVC 4 app. Amazing, worked with single go.

Now the thing is pretty clear that there is something wrong in MVC 4 app. Its time find the solution (well just a google search will do it).

Go to, configure service reference.

Select the option, Reuse types in specified referenced assemblies -> Check all except Newtonsoft.Json -> ok

Thats it. The proxy will be created now. We can do this while adding the service reference itself, by going to the Advanced window.

Note: Microsoft has fixed this issue in this update: http://support.microsoft.com/kb/2750149

The Cause (by microsoft): 
This issue occurs because the DataContractSerializer class has encountered a type 
(Newtonsoft.Json.Linq.JToken) that it does not support. In this case, it throws an exception, 
and then stops generating the service reference.

Conclusion: Since I am working in WCF after a long time I was continuously thinking that there is something wrong in my service and spent a lot of time to figure it out. Also, I missed one basic step in my tracing with which I could have saved my time (i.e. checking the Error List). Hope this article helps to someone else in future.

Out-of-interest, the error list was showing this error & warning.

Error:Custom tool error: Failed to generate code for the service reference 'ServiceReference1'.
Please check other error and warning messages for details.

Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Type 'Newtonsoft.Json.Linq.JToken' is a recursive collection data contract which is not supported. 
Consider modifying the definition of collection 'Newtonsoft.Json.Linq.JToken' to remove references to itself.