Wednesday, December 16, 2009

Consuming WCF service out of box

Consuming WCF service out of box: "

Hello All,

I found one issue while consuming WCF service from out of box, There are lots of threads I found for 'The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.' error, CommunicationObjectFaultedException exception thrown and 'The caller was not authenticated by the service.'

I spent lots of time in search, got bunch of solutions, some worked some does not, after doing lots of troubleshooting I got solution for my problem.

My case was, a web application running on different box is trying to consume WCF service which is hosted on different box, but some how on production it was not working. It always throws 'CommunicationObjectFaultedException'. Usually we are putting such calls in using blog, as its taking care of disposing object. But in case of WCF it may not work as per expected, the reason is; A CommunicationObjectFaultedException has been throws so you, the object is not yet initialized and you are using is trying to dispose method which again throw exception.

 

This is because using implicitly call Dispose at the closing brace, which may throw an exception because your object is not yet initialized as its in the Faulted state. To over come this a simple solution, use try catch and call Abort. More reading on this click Avoiding Problems with the Using Statement, good article form Microsoft including Sample application. During my search I found one good code delegate make you fell like you are using clause, but internally its handling such exception.

private class Util
{
public static void UsingWcf<T>(T client, Action<T> action)
where T : System.ServiceModel.ICommunicationObject
{

try
{
action(client);
client.Close();
}
catch (Exception)
{
client.Abort();
throw;
}
}
}
class Program
{
static void Main(string[] args)
{

Util.UsingWcf(new WcfClient(), c =>
{

});

/*using (WcfClient wcfClient = new WcfClient())
{
....
}// This will throw an error
*/
}
}

So we have caught CommunicationObjectFaultedException, but still we are not able to make call to service method. Now you can see one new error 'The caller was not authenticated by the service'. Cool we reach the service but its missing some credentials, as we are consuming service out of box.

Typical configuration section looks like following



Form error 'The caller was not authenticated by the service' we can guess that we need some credentials to call method. You can see the configuration; it says clientCredentialsType="Windows" and security mode is Message, generally with wsHttpBinding these are the typical settings.



As we are using Windows as credential type, we need to provide credentials to use WCF serverice out of box. Once this done you just need to pass user and password in ClientCredentials just like bellow

"

No comments: