Return significant WCF project exceptions

I am new to WCF in general. What little experience I get from using fairly simple .SVC services in ASP.NET web applications.

I first tried to experiment using the WCF project and ran into a major show stop.

As I am sure, most of them know for some strange reason in a web application in which customErrors mode is set to On

<customErrors mode = "On" /> 

Services (such as .ASMX and .SVC) will not return exception details to the client. Instead, the exception and stack traces are freed, and the message always reads "Request processing failed", which is not at all useful.

When services are directly hosted within the web application itself, it is easy to circumvent this limitation by placing the services in a dedicated folder and setting customErrors to “Off” for that folder.

However, Im works on the same issue with exceptions that are not returned from services that live in a separate WCF project. The fact is, I don’t know how to get around this.

In short: I need my WCF project services to throw REAL exceptions to the client — or at least the original exception message instead of “Request processing failed”.

EDIT . I should probably point out that the reason I want to throw exceptions is because I often call these services from the client side through Ajax (jQuery) and would like to format the returned message differently if it's "normal "return (for example, use green text), and then use red text if it is an error. I handle message formatting in the error handler of the $ .ajax object, which, obviously, will only be executed when the service fails.

I should also point out that everything works fine with customErrors Off:

 <customErrors mode = "Off" /> 

So, I think maybe there is some kind of configuration property that can be configured to stop ASP.NET runtime from my exception when using customErrors.

There is some related information here that I found on this.

+4
source share
3 answers

You have one more opportunity to catch exceptions that you want to bubble to the client, and to return service errors.

There is a bit more project work that needs to go on because you have to design the fault contracts yourself, but it gives you the flexibility to get back everything you want for the client. Thus, you can develop a contract that describes the error in detail, and a stack trace if you consider necessary.

Example:

 [DataContract(Namespace = "urn:// or http://....")] public class ClientNeedsToKnowFault { [DataMember] public List<Error> Errors { get { return _errors; } set { _errors = value; } } .... public ClientNeedsToKnowFault() { } public ClientNeedsToKnowFault(string message) { Message = message; Errors = new List<Error>() { new Error(message) }; } ... //Helper method to throw public static void ThrowFault(string message, List<Error> errorList) { throw new FaultException<ClientNeedsToKnowFault>(new ClientNeedsToKnowFault(message, errorList)); } 

Once you create your errors, you add an additional attribute to the service method.

 [FaultContract(typeof(ClientNeedsToKnowFault))] void MyServiceMethod(); 

And the last step would be to drop it. As you can see above, I just put a helper method to throw it, because I think the FaultException process is a little dirty.

I will say that the main argument of this approach is to catch a client-side error. But if the information is important enough to return an error, you probably want this complexity.

+3
source

The real answer here is that you probably always avoid the bubbles of real exceptions for the caller. The "ServiceResponse" template is useful here. The idea is that you return the "ServiceResponse" class, which contains any response values ​​that your service needs, but also has some kind of "IsError" flag in addition to the property that allows you to return an Exception object.

Then the service can simply handle all errors and return this information:

 public ServiceResponse MyService() { try { // ... do work here return new ServiceResponse { WhateverReturnValue = true }; } catch(Exception e) { return new ServiceResponse { IsError = true, Error = e }; } } 
+1
source

You can see how to implement the IErrorHandler interface to catch any exceptions and return the FaultException that is specified by your contract.

+1
source

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


All Articles