C# 如何确定asp.net web服务引发的异常类型?

C# 如何确定asp.net web服务引发的异常类型?,c#,asp.net,web-services,exception,soap,C#,Asp.net,Web Services,Exception,Soap,我有一个asp.NET web服务(不是WCF,而是带有WebMethods的经典的.asmx服务)抛出异常。所有异常都派生自两个基本异常类中的一个(都派生自异常): Web服务现在根据需要抛出异常。在我的客户端代码中,我可以捕获异常并看到如下消息: 服务器无法处理请求。-->没有找到任何文件 但是,异常的类型为FaultException(如我对捕获的异常执行.GetType()时所示)。调用客户机需要能够区分InputException和FatalException(并最佳地区分各个派生的异

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

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

服务器无法处理请求。-->没有找到任何文件

但是,异常的类型为FaultException(如我对捕获的异常执行.GetType()时所示)。调用客户机需要能够区分InputException和FatalException(并最佳地区分各个派生的异常,但这并不重要)。现在唯一的方法是解析消息,去掉“-->”前面的文本,然后打开文本。这显然不是最优的

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


简而言之,有没有一种方法可以让我从Web服务抛出自定义异常,并让调用客户端能够区分这些异常?

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

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

在WCF中,所有这些手动生成的故障节点都变得非常容易,在WCF中,您只需处理数据契约并捕获
FaultException

让我们举个例子。假设您有以下服务方法,该方法引发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
    }
}

就您的
InputException
FatalException
NoFilesFound
异常而言,它们很好,但应该留在服务器上。在您的web方法中捕获它们,并构建一个适当的
SoapException
,客户在使用该服务时能够理解它。

谢谢!我想知道我是否可以让我的自定义类从SoapException派生,然后使用构造函数来构建XmlNodes…@user1079591,是的,你可以,而且这实际上是一个很好的继续方法。所以我按照你的建议做了,但在客户端代码中,它不是作为SoapException捕获的,而是作为System.ServiceModel.FaultException捕获的。在我的代码中,我有两个catch块:一个用于SoapException,一个用于regular Exception,它总是转到regular Exception,当我在泛型上执行.GetType()时,它表示它的类型为System.ServiceModel.FaultException。@user1079591,这是因为您在客户端上使用了WCF。您已经使用VS中的
svcutil.exe
添加服务引用
生成了客户端代理。如果您想将其作为asmx web服务使用,可以使用
wsdl.exe
添加web引用
(仅当您针对.NET 2.0或更高版本时才可用)。啊,我明白了。事实上,我确实使用了“添加服务引用”。谢谢你的帮忙,我会修好的。
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
    }
}