WCF 4 Step By Step Chapter 3 Note (Fault Handling)

Interoperable services built using the WCF should convert .NET Framework exceptions intoSOAP faults and follow the SOAP specification for reporting these faults to client applications. The WCF library provides the FaultException class in the System.ServiceModel namespace. If a WCF service throws a FaultException object, the WCF runtime generates a SOAP fault message that is sent back to the client application.

Throwing and Catching a SOAP Fault

Server:
public List<string> ListProducts()
{
...
try
{
...
}
catch (Exception e)
{
// Edit the Initial Catalog in the connection string in app.config
// to trigger this exception
if (e.InnerException is System.Data.SqlClient.SqlException)
{
throw new FaultException(
"Exception accessing database: " +
e.InnerException.Message, new FaultCode("Connect to database"));
}
else
{
throw new FaultException(
"Exception reading product numbers: " +
e.Message, new FaultCode("Iterate through products"));
}
}
// Return the list of product numbers
return productsList;
}

Client:
try
{
// Obtain a list of all products
...
// Fetch the details for a specific product
...
// Query the stock level of this product
...
// Modify the stock level of this product
...
// Disconnect from the service
...
}
catch (FaultException e)
{
Console.WriteLine("{0}: {1}", e.Code.Name, e.Reason);
}


Using Strongly Typed Faults
Throwing a FaultException is very simple but is actually not as useful as it first appears.A client application must examine the FaultException object that it catches to determine the cause of the error, soit is not easy to predict what possible exceptions could occur when invoking a WCF service. A better solution is to use strongly typed SOAP faults.

Server:

[ServiceContract]
public interface IProductsService
{
// Get the product number of every product
[FaultContract(typeof(SystemFault))]
[FaultContract(typeof(DatabaseFault))]
[OperationContract]
List<string> ListProducts();

public List<string> ListProducts()
{
...
try
{
...
}
catch (Exception e)
{
// Edit the Initial Catalog in the connection string in app.config
// to trigger this exception
if (e.InnerException is System.Data.SqlClient.SqlException)
{
DatabaseFault dbf = new DatabaseFault
{
DbOperation = "Connect to database",
DbReason = "Exception accessing database",
DbMessage = e.InnerException.Message
};
throw new FaultException<DatabaseFault>(dbf);
}
else
{
...
}
}
...
}

Client:
static void Main(string[] args)
{
...
try
{
...
}
catch (FaultException<SystemFault> sf)
{
Console.WriteLine("SystemFault {0}: {1}\n{2}",
sf.Detail.SystemOperation, sf.Detail.SystemMessage,
sf.Detail.SystemReason);
}
catch (FaultException<DatabaseFault> dbf)
{
Console.WriteLine("DatabaseFault {0}: {1}\n{2}",
dbf.Detail.DbOperation, dbf.Detail.DbMessage,
dbf.Detail.DbReason);
}
catch (FaultException e)
{
Console.WriteLine("{0}: {1}", e.Code.Name, e.Reason);
}
...
}

Reporting Unanticipated Exceptions

If a service throws a strongly-typed exception that is not specified in the service contract, the details of the exception are not propagated to the client—the exception does not form part of the WSDL description of the operation used to generate the client proxy. There will inevitably be situations where it is difficult to anticipate the exceptions that an operation could throw

In the <serviceBehaviors> section, edit the <serviceDebug> element in the <behavior>
section and set the includeExceptionDetailInFaults attribute to true:

<?xml version="1.0"?>
<configuration>
...
<system.serviceModel>
...
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to
false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="false"/>
<!-- 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>

The previous exercise used the application configuration file to specify the serviceDebug
behavior for the service. You can perform the same task by using theServiceBehavior attribute
of the class that implements the service, like this:

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class ProductsServiceImpl : IProductsService
{
...
}

However, it is recommended that you enable this behavior only by using the application configuration file.


Managing Exceptions in Service Host Applications
ServiceHost States


Created:
Open:The ServiceHost object moves to the Opening state while it creates the channel stacks specified by the bindings for each endpoint and starts the service.
Close:Currently running requests are allowed to complete, but clients can no longer send new requests to the service.
Abort:This method closes the service immediately  without waiting for the service to finish processing client requests.

Handling Faults in a Host Application

using "ServiceHost" class

// ServiceHost object for hosting a WCF service
ServiceHost productsServiceHost;
productsServiceHost = new ServiceHost(...);
...
// Subscribe to the Faulted event of the productsServiceHost object
productsServiceHost.Faulted += (eventSender, eventArgs) =>
{
// FaultHandler method
// Runs when productsServiceHost enters the Faulted state
// Examine the properties of the productsServiceHost object
// and log the reasons for the fault
...
// Abort the service
productsServiceHost.Abort();
// Recreate the ServiceHost object
productsServiceHost = new ServiceHost(...);
// Start the service
productsServiceHost.Open();
};

Handling Unexpected Messages in a Host Application

// ServiceHost object for hosting a WCF service
ServiceHost productsServiceHost;
productsServiceHost = new ServiceHost(...);
...
// Subscribe to the UnknownMessageReceived event of the
// productsServiceHost object
productsServiceHost.UnknownMessageReceived += (eventSender, eventArgs) =>
{
// UnknownMessageReceived event handler
// Log the unknown message
...
// Display a message to the administrator
MessageBox.Show(string.Format(
"A client attempted to send the message: {0} ",
eventArgs.Message.Headers.Action));
};
...


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值