如何确定asp.net Web服务抛出的异常类型?

时间:2012-01-17 21:03:39

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

我有一个asp.NET Web服务(不是WCF,而是带有WebMethods的经典.asmx),它会抛出异常。所有异常都来自两个基本异常类之一(两者都派生自Exception):

public class InputException : Exception
{
   ....
}

public class FatalException : Exception
{
    ....
}

public class NoFilesFound: FatalException
{
   ....
}

....

Web服务现在根据需要抛出异常。在我的客户端代码中,我可以捕获异常并看到如下消息:

Server was unable to process request. ---> There were no files found

但是异常是FaultException类型(当我在捕获的异常上执行.GetType()时看到)。调用客户端需要能够区分InputException和FatalException(并且最佳地区分各个派生的但却不那么重要)。现在唯一的方法是解析消息,在“--->”之前删除文本并打开文本。这显然不是最佳的。

我知道我可以使用自定义代码抛出SoapExceptions但我希望尽可能避免这种情况。此外,它似乎是为那些处理XML的人而设计的,但是我们所有的web服务代码都没有触及XML,因为它已经为我们反序列化了。

简而言之,有没有办法让我从Web服务中抛出自定义异常,并让调用客户端能够区分异常?

1 个答案:

答案 0 :(得分:7)

处理此问题的正确方法是使用SoapException。所以你基本上会捕获服务上所有可能的异常,然后将它们转换为SoapException(我链接的文档包含一个示例),然后抛出这个自定义异常而不是抛出这个SoapException并包含你感兴趣的信息故障的Detail XML节点。

然后,当在客户端上调用服务时,您将能够捕获此SoapException并分析Detail XML节点以收集有关服务器上发生的故障的确切原因的更多详细信息。

在WCF中,所有这些手动生成的故障节点都非常简单,只需使用数据合同并捕获FaultException<SomeFaultContract>

让我们举个例子。假设您有以下服务方法抛出SoapException并在Details节点中提供有关错误的详细信息:

[WebMethod]
public string HelloWorld()
{
    var doc = new XmlDocument();
    var node = doc.CreateNode(
        XmlNodeType.Element, 
        SoapException.DetailElementName.Name, 
        SoapException.DetailElementName.Namespace
    );
    // you could actually use any sub nodes here
    // and pass even complex objects
    node.InnerText = "no files found";

    throw new SoapException(
        "Fault occurred", 
        SoapException.ClientFaultCode, 
        Context.Request.Url.AbsoluteUri, 
        node
    );
}

在使用它时,您可以在客户端上捕获此SoapException:

using (var client = new WebService1())
{
    try
    {
        var result = client.HelloWorld();
    }
    catch (SoapException ex)
    {
        var detail = ex.Detail;
        // detail.InnerText will contain the detail message
        // as detail is an XmlNode if on the server you have
        // provided a complex XML you would be able to fetch it here
    }
}

就您的InputExceptionFatalExceptionNoFilesFound例外情况而言,它们很好,但它们应保留在服务器上。在您的Web方法中捕获它们并构建一个适当的SoapException,客户端将能够理解何时使用该服务。