Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / XHTML

WCF DataContract with FaultException Details

4.00/5 (3 votes)
24 Jun 2009CPOL2 min read 52.2K   867  
WCF DataContract

Introduction

This is a simple WCF service and client application based on Microsoft Enterprise Library 4.1. and FaultException handling. The assumption based on Inventory.Core object for this application is how to use DataContract on the WCF service.

I have two methods, one returns all the products from the Products table as Array output and another one returns Name of the Product when WCF client sends the Product ID as input parameter.

Background

As native ASP.NET programmers, we must consider the SOA aspects when developing the WCF Webservice. Initially I did not care about how my WCF service was going to be functioning when non Microsoft technologies such as PHP, JSP and Perl implement the client application.

It's a good practice while designing the architecture of WCF or Webservice SOA that the developer must give considerable notice to other programming's data types and their type and signatures.

I made two mistakes when I was a newbie to WCF service. I always thought that my WCF service is going to be consumed by only an ASP.NET based application.

Simply we put it this way, "widely recognizable data types" that means general data type which paves way to smooth collaboration between my WCF and unknown client implementation code.

The second was the Exception handling part. I put all WCF related exceptions in my WCF service application such as CommunicationException and TimeoutException, etc. Even when I tested this WCF service on my consumer application, exceptions were not caught thoroughly despite being an ASP.NET client implementation for the WCF.

I don't know what kind of exception will be thrown when JSP or PHP based client application while my WCF service was on the wire.

These two factors were annoying me a lot in my development time. I rectified these problems by making customized error messages as understandable by other technologies.

Using the Code

C#
[FaultContractAttribute(typeof(FaultContractExceptionTest))]
// This will converts the system or application level exception into SOAP header format.
string[] AvailableProducts();   	//Instead of returning the CLR data type 
				//DataSet return the array type
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using System.Collections;
ArrayList al = new ArrayList();
string s = "";
Database db = DatabaseFactory.CreateDatabase();
DbCommand cmd = db.GetSqlStringCommand("SELECT * from Products");
DataSet ds = db.ExecuteDataSet(cmd);
foreach (DataRow dRow in ds.Tables[0].Rows)
{
 al.Add(dRow);
 }
foreach (Object row in al)
{
 s = s + ((DataRow)row)["ProductName"].ToString() + ",";

}
string rawString = s.TrimEnd(',').ToString();
string[] result = rawString.Split(',');
return result;

In my available Products implementation, I forcibly convert the DataSet into ArrayList type, then DataRow and array of string. This is because my intention was that JSP and PHP based consumer application should understand what type of data would be received from the WCF Service.

The second notifiable code snippet is as follows:

C#
catch (FaultException<FaultContractExceptionTest> fx)
{
fx.Detail.ErrorMessage = "Internal Server Error " + fx.Reason.ToString();
throw new FaultException<FaultContractExceptionTest>
	(new FaultContractExceptionTest(fx.Detail.ErrorMessage));
}

For FaultException class, use this implementation:

C#
[DataContractAttribute]
public class FaultContractExceptionTest
{
    private string Msg;
     public FaultContractExceptionTest(string msg)
    {
        this.Msg = msg;            
    }
    
    [DataMember]
    public string ErrorMessage
    {
        get { return this.Msg; }
        set { this.Msg = value; }
    }

For SOAP header message level exception handling purpose, I used the FaultContractExceptionTest class as DataContract as you can see here in my WSDL snippet:

XML
<wsdl:operation name="AvailableProducts">
<soap12:operation soapAction=http://tempuri.org/IService/AvailableProducts 
	style="document" /> 
- <wsdl:input>
<wsp:PolicyReference URI="#WSHttpBinding_IService_AvailableProducts_Input_policy" /> 
<soap12:body use="literal" /> 
</wsdl:input>
- <wsdl:output>
<wsp:PolicyReference URI="#WSHttpBinding_IService_AvailableProducts_output_policy" /> 
<soap12:body use="literal" /> 
</wsdl:output>
- <wsdl:fault name="FaultContractExceptionTestFault">
<wsp:PolicyReference 
 URI="#WSHttpBinding_IService_AvailableProducts_FaultContractExceptionTestFault_Fault" /> 
<soap12:fault name="FaultContractExceptionTestFault" use="literal" /> 
</wsdl:fault>
</wsdl:operation> 

History

  • 24th June, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)