Wednesday, August 24, 2011

Dreaded NotFound and Object reference not set to an instance of object exceptions in WCF RIA Services

Recently while developing an WCF RIA Services and SL4 client, I was facing these dreaded "NotFound" and "Object reference not set to an instance of object". After a bit of googling figured out the problem and its root cause.

NotFound exception

To view the actual error, you will have to use Fiddler. In the Fiddler, you can find out the actual error as "HTTP 404, Page Not Found error". This is because, WCF RIA service sits in the same virtual directory of you SL4 application. But the necessary config entries were not getting copied to the SL4 application config file.

For instance, When you create an RIA service and SL4 client; you will get the following projects in your solution;

xxxRIASerices.Host
xxxRIAServices.Host.Web

xxxSLRIAClient
xxxSLRIAClient.Web

The necessary config entries for enabling RIA service will be available in the App.Config file in xxxRIAServices.Host.Web (Basically the connectionStrings, System.Web, System.webServer sections). Copy those sections to xxxSLRIAClient.Web Web.Config file.

Bingo, we have get rid of the NotFound exception.

Object reference not set to an instance of object exception

I am sure, you will be getting this error. :) To solve this error, copy paste the System.ServiceModel section from xxxRIAServices.Host.Web App.Config to xxxSLRIAClient.Web Web.Config file.

Yes, now you should have get rid of these 2 exceptions and your WCF RIA service and SL client App will be working like charm.

Tuesday, August 23, 2011

EntityFramework and WCF

Recently while developing the WCF wrapper service for Entity Framework figured out that, the entities from EF cannot be used over the Channel. The reason was "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection". [You can capture this error if you enable WCF diagnostic logging].

There is a work around for this. You will have to use Data Transfer objects which mirror the entities from EF. So you can use those DTOs for tranmitting over the channel. It is not necessary that you will have to do this process manually, there are small add-ins available for doing this job. I used the EntitiesToDTO codeplex VS2010 add-in for this. So whenever we update the EF entities, just re-run this add-in which will update the DTOs based on the entities from EF.

PS - The transformation from entities to DTOs still need to be done by ourselves in the WCF operations.

Getting OperationContract name in WCF MessageDispatcher

There may be times where you need to identify the OperationContract name in WCF MessageDispatcher and do some processing based on that. Here is how you can do that;

In case of WCF Endpoint

In the AfterReceiveRequest method, do the following to get the Operation name;

MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
Message originalMessage = buffer.CreateMessage();
XmlDictionaryReader xmlDict = orginialMessage.GetReaderAtBodyContents();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlDict.ReadOuterXml());

string action = doc.DocumentElement.Name; //here you will get the OperationContract name

In case of WCF REST Endpoint

In the AfterReceiveRequest method, do the following to get the Operation name;



MessageProperties props = request.Properties;
string action = props["HttpOperationName"].ToString(); //here you will get the OperationContract name

Dreaded System.Security.SecurityException: Security Error... Silverlight and WCF REST

Recently I faced the dreaded System.Security.SecurityException: Security Error.. while developing the SL4 application consuming the WCF REST service. After a lot of trials fixed this dreaded issue. So thought of sharing my experince on SL4 consuming WCF REST service.

1) Ensure that crossdomain.xml and clientaccesspolicy.xml files are available in C:\Inetpub\wwwroot folder.
2) If you are using HTTPS, ensure the following;
  • Ensure clientaccesspolicy.xml contains explicit <domain uri="https://*"></domain>
  • Ensure only SSL access is enabled. The SL app and WCF REST service should not be accessible in HTTP mode.
  • Ensure crossdomain.xml contains <site-control permitted-cross-domain-policies="master-only"/> <allow-access-from domain="*" />
Do IISRESET. Then you should be able to get rid of this dreaded error.