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:
Client:
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:
Client:
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:
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:
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
Handling Unexpected Messages in a Host Application
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)); }; ...
相关文章推荐
- WCF 4 Step By Step Chapter 9 Note (Transaction)
- WCF 4 Step By Step Chapter 4 Note (Transport and Message Security + Authentication in Organization)
- WCF 4 Step By Step Chapter 10-12 Note (Reliable Sessions,ProgrammaticallyControlling, One-Way ...)
- WCF 4 Step By Step Chapter 7 Note(Maintaining State and Sequencing Operations)
- WCF 4 Step By Step Chapter 15 Note(Building REST Services)
- WCF 4 Step By Step Chapter 1,2 Note
- WCF 4 Step By Step Chapter 6 Note (Maintaining Service Contracts and Data Contracts)
- WCF 4 Step By Step Chapter 5 Note (Authentication in Internet)
- [WCF Step by Step 读书笔记] Chapter01 WCF 介绍
- Microsoft Press Windows Azure Step by Step Note
- [WCF Step by Step 读书笔记] Chapter02 寄宿一个WCF服务
- WCF自定义行为 Step by Step (五)Service和Client端自定义behavior的比较
- [WCF Step by Step 读书笔记] Chapter03 构造更强健的应用和服务
- Step by Step WCF—Instance Management
- SharePoint 2010之部署WCF(deploy WCF service to SharePoint 2010 via VS 2010 step by step)
- C# 2012 step by step 学习笔记8 CHAPTER 9 Creating Value types with enumerations and Structures
- [转载]Step By Step - Using Silverlight to Access a WCF Service Hosted In a Console Application
- C# step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型
- WCF自定义行为 Step by Step (一)搭建环境
- WCF自定义行为 Step by Step (二)第一个自定义行为