WCF REST Error Handling - Incorrect Entries

Summary:

In the WCF REST service, how can I handle invalid input parameters using my own custom error response?

detail:

I have an interface method in a WCF REST service:

[OperationContract] [WebGet(UriTemplate = "getitem?id={itemId}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] [FaultContract(typeof(DataModel.Fault))] DataModel.Item GetItem(int itemId); 

As part of my implementation of the GetItem method, I detect any error conditions (i.e. the element does not exist) and throws a WebFaultException. This works without any problems.

However, let's say the calling client calls the following URL:

http://myserver.com/itemservice/getitem?id=abc

i.e. input id value cannot be passed to int at the request of GetItem method

This call fails because the given id value is not reset to int, however, this failure occurs before any of my code is executed, and therefore I cannot return the DataModel.Fault object according to the FaultContract method assigned interface method.

So, the question is how can I connect a high-level error handler to catch errors of this type and subsequently return my own error structure, and not the HTML error that WCF generates:

Request Error A server error occurred while processing the request. See Server Logs for more information.

As a continuation of the same question, I would also like to be able to do the same if the client calls the following:

http://myserver.com/itemservice/gettitem?id=abc

note the typo in the URI, gettitem (two t) instead of getitem

+4
source share
1 answer

Use the IErrorHandler interface to extend your service.

This will allow you to provide an appropriate error for any exception. This post shows how to connect your own error handler to your service behavior.

I personally use one class to implement all the necessary elements, such as:

 public class ErrorSavingServiceBahavior : BehaviorExtensionElement, IServiceBehavior, IErrorHandler { private string m_sHostName; public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) { this.m_sHostName = serviceHostBase.Description.Name; foreach (ChannelDispatcher chanDisp in serviceHostBase.ChannelDispatchers) { if (!chanDisp.ErrorHandlers.Contains(this)) { chanDisp.ErrorHandlers.Add(this); } } } public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) { } public bool HandleError(Exception error) { //my custom code } public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault) { //my custom code } public override Type BehaviorType { get { return this.GetType(); } } protected override object CreateBehavior() { return this; } } 

and web.config I continue:

 <behaviors> <serviceBehaviors> <behavior name="BehaviorName"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true"/> <saveExceptions /> </behavior> </serviceBehaviors> </behaviors> <extensions> <behaviorExtensions> <add name="saveExceptions" type="Namespace.Class, DLLName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> </behaviorExtensions> </extensions> 
+1
source

Source: https://habr.com/ru/post/1413971/


All Articles