【问题标题】:Catching a custom Exception thrown by a WebMethod on ASP.NET WebService捕获由 ASP.NET WebService 上的 WebMethod 引发的自定义异常
【发布时间】:2011-04-19 20:28:45
【问题描述】:

我有一个经典的 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 服务引用时,我有服务类、输入和输出类,但我没有自定义异常类。

另外一个问题是,我在序列化 Exception 类方面也有问题(因为 Exception.Data 属性实现了 IDictionary 接口)

有没有办法以我的方式做到这一点,或者我的方式完全错误,或者我错过了 Web 服务的基础知识?

谢谢。

【问题讨论】:

    标签: c# asp.net web-services exception


    【解决方案1】:

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

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

    我的问题基本上解决了如下:

    网络服务:

    [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 服务异常的有用信息。

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

    How to: Handle Exceptions Thrown by a Web Service Method

    【讨论】:

    • 您需要在 web.config 中设置 customErrors mode='RemoteOnly' 或 'On'
    【解决方案2】:

    This 可能会有所帮助。看起来您会收到 SoapException,但您可以检查详细信息以确定它是否属于您的类。

    旁注,要访问“HelloWorldException”,您可以将其拉出到单独的程序集中并将其部署到客户端...

    【讨论】:

    • 您分享的链接对布莱斯很有帮助。谢谢。这有助于我了解 Web 服务异常的行为。但是,将异常类部署到客户端将是我较晚的选择。我会考虑一段时间。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    相关资源
    最近更新 更多