Exception Handling in WCF

Source: Internet
Author: User
Exception messages are related to specific technologies. The same is true for. Net exceptions. Therefore, WCF does not support traditional exception handling methods. If the exception is handled in a traditional way in the WCF Service, the client cannot receive the exception thrown by the service because the exception message cannot be serialized. For example, this service design:
[Servicecontract (sessionmode = sessionmode. Allowed)]
Public interface idocumentsexplorerservice
{
[Operationcontract]
Documentlist fetchdocuments (string homedir );
}
[Servicebehavior (instancecontextmode = instancecontextmode. Single)]
Public class documentsexplorerservice: idocumentsexplorerservice, idisposable
{
Public documentlist fetchdocuments (string homedir)
{
// Some codes

If (directory. exists (homedir ))
{
// Fetch documents according to homedir
}
Else
{
Throw new directorynotfoundexception (
String. Format ("directory {0} is not found.", homedir ));
}
}
Public void dispose ()
{
Console. writeline ("the service had been disposed .");
}
}

When the client calls the preceding service operation, the exception cannot be obtained using the following capture method:
Catch (directorynotfoundexception ex)
{
// Handle the exception;
}

To make up for this defect, WCF treats unrecognized exceptions as faultexception exception objects. Therefore, the client can capture faultexception or exception exceptions:
Catch (faultexception ex)
{
// Handle the exception;
}
Catch (exception ex)
{
// Handle the exception;
}

However, exceptions captured in this way cannot identify the error message passed by directorynotfoundexception. It is particularly serious that such exception handling method will also cause an error in the channel for passing the message. When the client continues to call the service operation of the service proxy object, it will get a communicationobjectfaultedexception exception, you cannot continue using the service. If the service is set to persession or single mode, an exception may also cause the service object to be released and the service is terminated.

WCF provides the faultcontract feature for exception handling. It can be applied to service operations to specify the types of exceptions that an operation may throw. For example, the preceding service contract can be changed to:
[servicecontract (sessionmode = sessionmode. allowed)]
Public interface idocumentsexplorerservice
{< br> [operationcontract]
[faultcontract (typeof (directorynotfoundexception)]
documentlist fetchdocuments (string homedir);
}

However, even if the exception to be thrown is specified through faultcontract, if the exception thrown by the service is not faultexception or faultexception , a channel error occurs. Therefore, in service implementation, the correct implementation should be as follows:
public class documentsexplorerservice: idocumentsexplorerservice, idisposable
{< br> Public documentlist fetchdocuments (string homedir)
{< br> // some codes
If (directory. exists (homedir ))
{< br> // fetch documents according to homedir
}< br> else
{< br> directorynotfoundexception exception = new directorynotfoundexception ();
throw new faultexception (exception,
New faultreason (string. format ("directory {0} is not found. ", homedir);
}< BR >}

We can use the exception type to be thrown by the Service as the type parameter of faultexception <t>, and then create a faultreason object to pass the error message. When the client calls a Service proxy object, it can capture the faultexception <directorynotfoundexception> exception, and the exception does not cause a channel error, and the client can continue to use the service proxy object. Even if the service is a percall service, the client can continue to call the service operation. If the service is a session service or Singleton service, even if an exception occurs, the service object will not be terminated.

If you only want the client to obtain the exception message, even if you do not apply the faultcontract feature or throw a non-faultexception exception, you can also use the servicebehavior feature, set includeexceptiondetailinfaults of the Service to true (false by default). At this time, the client can capture the non-faultexception exception thrown, but this exception still causes channel errors.

However, when releasing and deploying services, we should avoid setting includeexceptiondetailinfaults to true.

If you do not want to use faultcontract, and ensure that exceptions thrown by the service can be caught by the client without causing channel errors, you can also implement this through error processing extension. In this case, the service itself can be used as an error handling object to implement the system. servicemodel. Dispatcher. ierrorhandler interface:
Public class documentsexplorerservice: idocumentsexplorerservice, ierrorhandler, idisposable
{...}

In the providefault () method of this interface, you can increase the non-faultcontract exception to faultcontract <t> exception, for example, to raise the directorynotfoundexception exception to faultexceptino <directorynotfoundexception> exception:
Public void providefault (Exception error, messageversion version, ref message fault)
{
If (error is directorynotfoundexception)
{
Faultexception <directorynotfoundexception> faultexception = new faultexception <directorynotfoundexception> (
New directorynotfoundexception (), new faultreason (error. Message ));
Messagefault = faultexception. createmessagefault ();
Fault = message. createmessage (version, messagefault, faultexception. action );
}
}

In the handleerror () method of this interface, exception errors can be handled, such as logging.

To make the error handling extension take effect, you also need to install the error handling extension to the service channel. The method is to enable the Service class to implement the system. servicemodel. description. iservicebehavior interface:
Public class documentsexplorerservice: idocumentsexplorerservice, ierrorhandler, iservicebehavior, idisposable
{...}

Then install the error handling extension in the applydispatchbehavior () method:
Public void applydispatchbehavior (servicedescription, servicehostbase)
{
Foreach (channeldispatcher Dispatcher in servicehostbase. channeldispatchers)
{
Dispatcher. errorhandlers. Add (this );
}
}

Through such processing, even if the exception thrown by the service is a directorynotfoundexception exception and the exception is not specified through the faultcontract feature in the service contract, the client can also obtain the Exception error information, if this exception does not cause a channel error, the client can continue to call the operation of the service proxy object.

This Article has been published in it168 : http://tech.it168.com/msoft/2007-12-03/200712031939709.shtml

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.