Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception Handling in WCF REST Full Service

I am developing REST Full API using WCF Service 4.5 F/W. Please suggest how to send exception or any business validation messages to client. I am looking for a very generic solution please suggest the best ways of doing it. I have tried some approaches below,

  1. Set OutgoingWebResponseContext before sending response to client.

  2. Defined Fault contract that is working fine only Adding service reference(proxy class) not working in REST FULL environment.

  3. Adding WebFaultException class in catch block.

  4. WCF Rest Starter Kit - I got some articles and posts regarding this but their CodePlex official sit suggested no longer this available. link. So, I don't want to go with this.

These are not working as expected.. My sample Code Snippet: Interface:

    [OperationContract]
    [FaultContract(typeof(MyExceptionContainer))]
    [WebInvoke(Method = "GET", UriTemplate = "/Multiply/{num1}/{num2}", BodyStyle = WebMessageBodyStyle.Wrapped,RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
    string Multiply(string num1, string num2);

Implementation:

         public string Multiply(string num1, string num2)
    {
        if (num1 == "0" || num2 == "0")
        {
            try
            {
                MyExceptionContainer exceptionDetails = new MyExceptionContainer();
                exceptionDetails.Messsage = "Business Rule violatuion";
                exceptionDetails.Description = "The numbers should be non zero to perform this operation";
                //OutgoingWebResponseContext outgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse;
                //outgoingWebResponseContext.StatusCode = System.Net.HttpStatusCode.ExpectationFailed;
                //outgoingWebResponseContext.StatusDescription = exceptionDetails.Description.ToString();
               // throw new WebFaultException<MyExceptionContainer>(exceptionDetails,System.Net.HttpStatusCode.Gone);
                throw new FaultException<MyExceptionContainer>(exceptionDetails,new FaultReason("FaultReason is " + exceptionDetails.Messsage + " - " + exceptionDetails.Description));
            }
            catch (Exception ex)
            {
                throw new FaultException(ex.Message);
            }
        }

        return Convert.ToString(Int32.Parse(num1) * Int32.Parse(num2));
    }

Web.Config :

  <system.serviceModel>
<services>
  <service name="TestService.TestServiceImplementation" behaviorConfiguration="ServiceBehaviour">
    <endpoint binding="webHttpBinding" contract="TestService.ITestService" behaviorConfiguration="webHttp" >
    </endpoint>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehaviour">
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true"/>
      <!-- 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>
  <endpointBehaviors>
    <behavior name="webHttp" >
      <webHttp helpEnabled="true" faultExceptionEnabled="true"/>
    </behavior>
  </endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

Client :

try
        {
            string serviceUrl = "http://localhost:51775/TestService.cs.svc/Multiply/0/0";
            //Web Client
            //WebClient webClient = new WebClient();
            //string responseString = webClient.DownloadString(serviceUrl);
            WebRequest req = WebRequest.Create(serviceUrl);
            req.Method = "GET";
            req.ContentType = @"application/xml; charset=utf-8";
            HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
            if (resp.StatusCode == HttpStatusCode.OK)
            {
                XmlDocument myXMLDocument = new XmlDocument();
                XmlReader myXMLReader = new XmlTextReader(resp.GetResponseStream());
                myXMLDocument.Load(myXMLReader);
                Console.WriteLine(myXMLDocument.InnerText);
            }
            Console.ReadKey();
        }
        catch (Exception ex)
        { 
        Console.WriteLine(ex.Message);
        }

This is my first Question, Thank You to All Passionate Developers..!

like image 376
SJ Alex Avatar asked Sep 27 '14 02:09

SJ Alex


People also ask

Which type of exception can be thrown from WCF service?

Fault exceptions are exceptions that are thrown by a WCF service when an exception occurs at runtime -- such exceptions are typically used to transmit untyped fault data to the service consumers.

Is it possible to use RESTful services using WCF?

You can use WCF to build RESTful services in . NET. REST (Representational State Transfer) is an architecture paradigm that conforms to the REST architecture principles. The REST architecture is based on the concept of resources: It uses resources to represent the state and functionality of an application.

Which property must be set in WCF configuration to allow users to see exception details of a WCF methods?

It is mandatory to provide the typeof property with FaultContract. Also, if no fault contract attribute is applied, the default exception that will be returned by WCF will be of type FaultException. Run the WCF test client and invoke the method. We can see the details of the custom message that we set.


1 Answers

Instead of FaultException, use the following:

Server:

catch (Exception ex)
            {
                throw new System.ServiceModel.Web.WebFaultException<string>(ex.ToString(), System.Net.HttpStatusCode.BadRequest);
            }

The Client:

catch (Exception ex)
            {
                var protocolException = ex as ProtocolException;
                var webException = protocolException.InnerException as WebException;
                if (protocolException != null && webException != null)
                {
                    var responseStream = webException.Response.GetResponseStream();
                    var error = new StreamReader(webException.Response.GetResponseStream()).ReadToEnd();
                    throw new Exception(error);
                }
                else
                    throw new Exception("There is an unexpected error with reading the stream.", ex);

            }
like image 118
DJ' Avatar answered Oct 07 '22 13:10

DJ'