Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>EDIT:</strong> Updated the post with a proper custom json error handler</p> <h2>The quick but non-preffered way.</h2> <pre><code>&lt;serviceDebug includeExceptionDetailInFaults="true"/&gt; </code></pre> <p>In Your service behavior will give you all the details you need.</p> <h2>The Nice way</h2> <p>All exceptions from the application are converted to an <code>JsonError</code> and serialized using a <code>DataContractJsonSerializer</code>. The <code>Exception.Message</code> is used directly. FaultExceptions provide the FaultCode and other exception are threated as unknown with faultcode -1.</p> <p>FaultException are sent with HTTP status code 400 and other exceptions are HTTP code 500 - internal server error. This not nescessary as the faultcode can be used to decide if it is and unknown error. It was however convenient in my app.</p> <p><strong>The error handler</strong></p> <pre><code>internal class CustomErrorHandler : IErrorHandler { public bool HandleError(Exception error) { //Tell the system that we handle all errors here. return true; } public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault) { if (error is FaultException&lt;int&gt;) { FaultException&lt;int&gt; fe = (FaultException&lt;int&gt;)error; //Detail for the returned value int faultCode = fe.Detail; string cause = fe.Message; //The json serializable object JsonError msErrObject = new JsonError { Message = cause, FaultCode = faultCode }; //The fault to be returned fault = Message.CreateMessage(version, "", msErrObject, new DataContractJsonSerializer(msErrObject.GetType())); // tell WCF to use JSON encoding rather than default XML WebBodyFormatMessageProperty wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json); // Add the formatter to the fault fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf); //Modify response HttpResponseMessageProperty rmp = new HttpResponseMessageProperty(); // return custom error code, 400. rmp.StatusCode = System.Net.HttpStatusCode.BadRequest; rmp.StatusDescription = "Bad request"; //Mark the jsonerror and json content rmp.Headers[HttpResponseHeader.ContentType] = "application/json"; rmp.Headers["jsonerror"] = "true"; //Add to fault fault.Properties.Add(HttpResponseMessageProperty.Name, rmp); } else { //Arbitraty error JsonError msErrObject = new JsonError { Message = error.Message, FaultCode = -1}; // create a fault message containing our FaultContract object fault = Message.CreateMessage(version, "", msErrObject, new DataContractJsonSerializer(msErrObject.GetType())); // tell WCF to use JSON encoding rather than default XML var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json); fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf); //Modify response var rmp = new HttpResponseMessageProperty(); rmp.Headers[HttpResponseHeader.ContentType] = "application/json"; rmp.Headers["jsonerror"] = "true"; //Internal server error with exception mesasage as status. rmp.StatusCode = System.Net.HttpStatusCode.InternalServerError; rmp.StatusDescription = error.Message; fault.Properties.Add(HttpResponseMessageProperty.Name, rmp); } } #endregion } </code></pre> <p><strong>Webbehaviour used to install the above error handler</strong></p> <pre><code>internal class AddErrorHandlerBehavior : WebHttpBehavior { protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { base.AddServerErrorHandlers(endpoint, endpointDispatcher); //Remove all other error handlers endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear(); //Add our own endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new CustomErrorHandler()); } } </code></pre> <p><strong>The json error data contract</strong></p> <p>Specifies the json error format. Add properties here to change the error format.</p> <pre><code>[DataContractFormat] public class JsonError { [DataMember] public string Message { get; set; } [DataMember] public int FaultCode { get; set; } } </code></pre> <p><strong>Using the error handler</strong></p> <p>Self-hosted</p> <pre><code>ServiceHost wsHost = new ServiceHost(new Webservice1(), new Uri("http://localhost/json")); ServiceEndpoint wsEndpoint = wsHost.AddServiceEndpoint(typeof(IWebservice1), new WebHttpBinding(), string.Empty); wsEndpoint.Behaviors.Add(new AddErrorHandlerBehavior()); </code></pre> <p>App.config</p> <pre><code>&lt;extensions&gt; &lt;behaviorExtensions&gt; &lt;add name="errorHandler" type="WcfServiceLibrary1.ErrorHandlerElement, WcfServiceLibrary1" /&gt; &lt;/behaviorExtensions&gt; &lt;/extensions&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload