捕获ASP.NET WebService中WebMethod抛出的自定义异常

9

我有一个经典的asp.net web服务(asmx),其中包含一个Web方法。在我的Web方法中,我需要针对某些情况抛出自定义异常,并且我需要在调用web服务方法时捕获该特定的自定义异常。

[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);
        }
    }
}

以下是输入、输出和异常类的示例:

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) { }
}

在客户端,我需要:
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
    }
}

然而,我无法这样做,因为当我在客户端添加Web服务引用时,我有了服务类、输入和输出类,但是没有自定义异常类。

另一个问题是,由于异常的Data属性实现了IDictionary接口,我也有序列化异常类的问题。

是否有一种方法可以按照我的方式解决这个问题,或者我完全错了,或者我在Web服务的基本原理方面漏掉了一些内容?

谢谢。

2个回答

11

ASP.NET Web Service可以抛出任何类型的异常:SoapException、HelloWorldException或其他异常。然而,异常被序列化为SOAP Fault元素,并且无论服务中抛出的异常类型是什么,异常在反序列化时都会转换为SoapException。因此,即使我将HelloWorldException部署到客户端,也无法使用我的catch块捕获它。

对于ASP.NET客户端,唯一的方法是将异常作为SoapException捕获,并通过其Actor或SoapFaultSubCode属性进行处理。

我基本上通过以下方式解决了我的问题:

Web服务:

[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);
        }
    }
}

客户端:

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
    }
}

除了Bryce Fischer在他的答案中写的文档之外,这些msdn文档也提供了关于抛出和处理Web服务异常的有用信息。

如何:从使用ASP.NET创建的Web服务中抛出异常

如何:处理由Web服务方法引发的异常


你需要在你的web.config中设置customErrors mode='RemoteOnly'或者'On'。 - eddy

4

这篇文章可能会对您有所帮助。看起来您会收到一个SoapException异常,但是您可以检查详细信息以确定它是否与您的类有关。

另外,为了访问"HelloWorldException",您可以将其拆分成独立的程序集并部署到客户端...


你分享的链接非常有用,Bryce。谢谢。那帮助我理解了Web服务异常的行为。然而,将异常类部署到客户端对我来说可能是一个晚期选择。我会再考虑一段时间。非常感谢。 - Musa Hafalir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接