您的位置:首页 > 其它

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

2012-03-13 23:48 344 查看
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 theFaultException
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));
};
...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: