Handling wcf
service exceptions using fault contracts and data contracts.
WCF gives you enough
flexibility to handle exceptions and send required detail to clients.
By default WCF sends exception details to clients using SOAP
FaultContract. The default FaultContract will allow you to set
Message, Reason properties and throw it to clients.
Why
we should use the FaultContract rather than using. Net
exceptions?
Exceptions has limitations and security risks.
Exceptions has limitations and security risks.
-
.Net exception can be used by only CLR supported languages so loosing great WCF feature of interoperability.
-
Throwing exceptions can provide service implementation and private details to clients.
-
Exceptions are tightly coupled between clients and service.
1. Service
Implementation
namespace FaultContractSampleWCF
{
// NOTE: You can use the "Rename" command on the
// "Refactor" menu to change the interface name
// "IService" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
[FaultContract(typeof(ServiceData))]
ServiceData TestConnection(string strConnectionString);
}
// Use a data contract as illustrated in the sample
// below to add composite types to service operations.
[DataContract]
public class ServiceData
{
[DataMember]
public bool Result { get; set; }
[DataMember]
public string ErrorMessage { get; set; }
[DataMember]
public string ErrorDetails { get; set; }
}
}
namespace FaultContractSampleWCF
{
// NOTE: You can use the "Rename" command on the "Refactor"
// menu to change the class name "Service1" in code, svc and config file together.
public class Service1 : IService1
{
/// <summary>
/// Implement the TestConnection method.
/// </summary>
/// <returns></returns>
public ServiceData TestConnection(string StrConnectionString)
{
ServiceData myServiceData = new ServiceData();
try
{
SqlConnection con = new SqlConnection(StrConnectionString);
con.Open();
myServiceData.Result = true;
con.Close();
return myServiceData;
}
catch (SqlException sqlEx)
{
myServiceData.Result = true;
myServiceData.ErrorMessage = "Connection can not open this " +
"time either connection string is wrong or Sever is down. Try later";
myServiceData.ErrorDetails = sqlEx.ToString();
throw new FaultException<ServiceData>(myServiceData, sqlEx.ToString());
}
catch (Exception ex)
{
myServiceData.Result = false;
myServiceData.ErrorMessage = "unforeseen error occurred. Please try later.";
myServiceData.ErrorDetails = ex.ToString();
throw new FaultException<ServiceData>(myServiceData, ex.ToString());
}
}
}
}
The
following endpoint details are automatically added to web.cofig
when
you create a WCF Service Project.<services> <service name="FaultContractSampleWCF.Service1" behaviorConfiguration="FaultContractSampleWCF.Service1Behavior"> <!-- Service Endpoints --> <endpoint address="" binding="wsHttpBinding" contract="FaultContractSampleWCF.IService1"> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services>
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior> <!-- To avoid disclosing metadata information, set the value below to false before deployment --> <serviceMetadata httpGetEnabled="true"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true.
Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel>
Consuming the
Services:
namespace Client_FaultContractSampleWCF { class Program { static void Main(string[] args) { try { Service1Client objServiceClient = new Service1Client(); //Pass the connection string to the TestConnection Method. ServiceData objSeviceData = objServiceClient.TestConnection( @"integrated security=true;data source=localhost;initial catalog=master"); if (objSeviceData.Result == true) Console.WriteLine("Connection Succeeded"); Console.ReadLine(); } catch (FaultException<ServiceData> Fex) { Console.WriteLine("ErrorMessage::" + Fex.Detail.ErrorMessage + Environment.NewLine); Console.WriteLine("ErrorDetails::" + Environment.NewLine + Fex.Detail.ErrorDetails); Console.ReadLine(); } } } }
No comments:
Post a Comment