Catching a custom Exception thrown by a WebMethod on ASP.NET WebService

27,554

Solution 1

ASP.NET Web Service can throw any type of exception: SoapException, HelloWorldException or soever. However, the exception is serialized into a SOAP Fault element, and regardless of the type of the exception thrown in the service, the exception is converted into a SoapException while deserialization. Hence, it is not possible to catch the HelloWorldException with my catch block in my question, even if I deploy the HelloWorldException to the client.

For an ASP.NET client, the only way is to catch the exception as SoapException and handle it by its Actor or SoapFaultSubCode property.

I've basically solved my problem as below:

Web Service:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
    [WebMethod]
    public HelloWorldOutput HelloWorld(HelloWorldInput input)
    {
        try
        {
            // My Code
            return new HelloWorldOutput();
        }
        catch (Exception ex)
        {
            throw new SoapException("Hello World Exception",   
                 SoapException.ServerFaultCode, "HelloWorld", ex);
        }
    }
}

Client:

public static void Main()
{
    WebService service = new WebService();
    try
    {
        service.HelloWorld(new HelloWorldInput());
    }
    catch (SoapException ex)
    {
        if(ex.Actor == "HelloWorld")
            // Do sth with HelloWorldException
    }
    catch (Exception ex)
    {
        // Do sth with Exception
    }
}

Together with the document which Bryce Fischer wrote in his answer; these msdn documents also has helpful information about throwing and handling web service exceptions.

How to: Throw Exceptions from a Web Service Created Using ASP.NET

How to: Handle Exceptions Thrown by a Web Service Method

Solution 2

This may be of help. Looks like you'll get a SoapException, but you can inspect the details to determine if its your class or not.

Side note, to have access to "HelloWorldException", you can pull it out into a seperate assembly and deploy that on the client...

Share:
27,554
Musa Hafalır
Author by

Musa Hafalır

I have been developing software for 4 years commonly using .NET technologies.

Updated on November 26, 2020

Comments

  • Musa Hafalır
    Musa Hafalır over 3 years

    I have a classical asp.net web service (asmx) and a web method in it. I need to throw a custom exception for some case in my web method, and I need to catch that specific custom exception where I call the web service method.

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class WebService : System.Web.Services.WebService
    {
        [WebMethod]
        public HelloWorldOutput HelloWorld(HelloWorldInput input)
        {
            try
            {
                // My Code
                return new HelloWorldOutput();
            }
            catch (Exception ex)
            {
                throw new HelloWorldException("Hello World Exception", ex);
            }
        }
    }
    

    Input, output and exception classes as a sample:

    public class HelloWorldInput { }
    public class HelloWorldOutput { }    
    
    [Serializable]
    public class HelloWorldException : Exception
    {
        public HelloWorldException() { }
        public HelloWorldException(string message) : base(message) { }
        public HelloWorldException(string message, Exception inner) 
            : base(message, inner) { }
        protected HelloWorldException(
          System.Runtime.Serialization.SerializationInfo info,
          System.Runtime.Serialization.StreamingContext context)
            : base(info, context) { }
    }
    

    In the client side, I need:

    public static void Main()
    {
        WebService service = new WebService();
        try
        {
            service.HelloWorld(new HelloWorldInput());
        }
        catch (HelloWorldException ex)
        {
            // Do sth with HelloWorldException
        }
        catch (Exception ex)
        {
            // Do sth with Exception
        }
    }
    

    However, I cannot do that because when I add the web service reference on the client, I have service class, input and output classes, but I do not have custom exception class.

    Also another problem is that, I have also problems with serializing Exception class (because of Exception.Data property implements IDictionary interface)

    Is there a way to do this in my way, or am I in a completely wrong way, or is there something I miss about fundamentals of web services?

    Thanks.

  • Musa Hafalır
    Musa Hafalır over 13 years
    The link you have shared was very helpful Bryce. Thanks. That help me realize the behaviour of web service exceptions. However, deploying the exception class to the client will be a late choice for me. I will think about the subject for a while. Thanks a lot.
  • eddy
    eddy over 10 years
    You need to set customErrors mode='RemoteOnly' or 'On' in your web.config