none
Can't return generic WebFaultException<> with details object on an Ajax enabled service RRS feed

  • Question

  • When I throw a WebFaultException<CustomClass>, I only get a an object of type FaultException on the client side - not the specific class.  If I set IncludeExceptionDetailsInFaults to true, then I can see it set the message in the fault as the status code description, but I still don't have any of my fault details ....  I was really hoping fault details would work just like a regular wcf service.   I briefly looked at the ErrorHandler the WebScriptEnablingBehavior in Reflector, and it doesn't look it was written to handle any custom fault details ....  I really hope I'm wrong here.

     
      [DataContract]
        public class TestFault
        {
            [DataMember]
            public string Data { get; set; }
        }
    
        [ServiceContract]
        public interface ITestService
        {
            [FaultContract(typeof(TestFault))]
            [OperationContract]
            void Test();
        }
    
        [ServiceBehavior]
        public class TestService : ITestService
        {
            public void Test()
            {
                throw new WebFaultException<TestFault>(new TestFault() { Data = "test" }, System.Net.HttpStatusCode.BadRequest);
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
    
                WebScriptServiceHostFactory factory = new WebScriptServiceHostFactory();
                ServiceHost host = new ServiceHost(typeof(TestService), new Uri("http://localhost/TestService"));
                ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITestService), new WebHttpBinding(), "");
                endpoint.Behaviors.Add(new WebScriptEnablingBehavior());
                host.Open();
    
                ChannelFactory<ITestService> channelFactory = new ChannelFactory<ITestService>(new WebHttpBinding(), "http://localhost/TestService");
                channelFactory.Endpoint.Behaviors.Add(new WebScriptEnablingBehavior());
                ITestService channel = channelFactory.CreateChannel();
                channel.Test();
    
            }
        }

       
    Tuesday, July 24, 2012 4:21 PM

All replies

  • You are creating channel and channelfactory so it will work more like a SOAP protocol not REST

    "When using a WCF REST endpoint (WebHttpBinding and WebHttpBehavior or WebScriptEnablingBehavior) the HTTP status code on the response is set accordingly. However, WebFaultException can be used with non-REST endpoints and behaves like a regular FaultException.

    When using a WCF REST endpoint, the response format of the serialized fault is determined in the same way as a non-fault response. For more information about WCF REST formatting, see WCF REST Formatting."

    I would suggest you to Use REST Api if you want to use WebFaultException. Below is an example how you can use WebFaultException using REST

    var r = httpWebRequest.GetResponse(); 
    if(r.StatusCode != 200) {     
    MessageBox.Show(r.Content); // Display the error  
    } 
    else 
    {    
     var streamIn 
           = new StreamReader(r.GetResponseStream());     
    string strResponse = streamIn.ReadToEnd();     streamIn.Close();     return strResponse; 
    } 


    Tanvir Huda Application Architect/Consultant http://thetechnocrate.wordpress.com/

    Wednesday, July 25, 2012 3:22 AM
  • In my service, if I do

    throw new WebFaultException<MyCustomFaultClass>(faultOb, HttpStatusCode.BadRequest)

    then in my client code, I'd like to catch that exception.

    So I'd do something like this:

    try { channel.ExecuteMethod(); } catch(WebFaultException<CustomFaultClass> wfe) { //get my faultobj via wfe.Detail //get status code via wfe.StatusCode }


    But this doesn't seem to work. How are people supposed to access the .Detail on their WebFaultException client side?

    Wednesday, July 25, 2012 12:37 PM
  • Hi,

    Check this sample:

    WCF REST tip 2: WebFaultException

    http://pieterderycke.wordpress.com/2011/04/30/wcf-rest-tip-2-webfaultexception/

    Thursday, July 26, 2012 9:20 AM
  • Thanks for the link.

    If using the WebHttpBehavior, then yes, the fault information does get sent.  But I can't get at it the typical WCF way.  When using WebScriptEnablingBehavior I don't get the fault details at all - it doesn't appear to send it.  I would argue this is a bug in the REST portion of the WCF stack.

    If using WebHttpBehavior, I have to use HttpWebRequest like this: 

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost/TestService/Test");
                request.Method = "POST";
                request.ContentLength = 0;
                request.ContentType = "application/json";
                try
                {
                    var response = (HttpWebResponse)request.GetResponse();
                }
                catch (WebException we)
                {
                    var response = (HttpWebResponse)we.Response;
                    Stream responseStream = response.GetResponseStream();
                    if (response.StatusCode == HttpStatusCode.InternalServerError)
                    {
                        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(TestFault));
                        TestFault fault = (TestFault)serializer.ReadObject(responseStream);
                        Console.WriteLine(fault.Data);
    
                    }
                }

    This DOESN'T work:

                ChannelFactory<ITestService> channelFactory = new ChannelFactory<ITestService>(new WebHttpBinding(), "http://localhost/TestService");
                channelFactory.Endpoint.Behaviors.Add(new WebHttpBehavior());
                ITestService channel = channelFactory.CreateChannel();
                try
                {
                    channel.Test();
                }
                catch(WebFaultException<TestFault> wfe)
                {
                    Console.WriteLine(wfe.Detail.Data);
                    Console.WriteLine(wfe.StatusCode);
                }


    • Edited by Lars Fiedler Thursday, July 26, 2012 2:10 PM removed servicehost code
    Thursday, July 26, 2012 2:09 PM
  • It's too late to answer, but maybe will help somebody.

    According to MSDN Article about WebFaultException<T> Class (sorry, can't insert link), in SOAP client WebFaultException<T> behaves like a regular FaultException, so to get detailed message, try this:


    try
    {
        channel.Test();
    }
    catch (FaultException fe)
    {
        MessageFault mf = fe.CreateMessageFault();
        string errorDetail = null;
        Console.WriteLine("Status code: " + fe.Message)
        if (mf.HasDetail)
        {
            TestFault errorData = mf.GetDetail<TestFault>();
            if (errorData != null)
            {
                errorDetail = errorData.Data;
            }
        }
        Console.WriteLine("Error details: " + (errorDetail ?? "<no_data>"));
    }
    Hope this help

    Wednesday, November 13, 2013 11:33 AM