如何从ASP.NET中的肥皂异常中提取内部异常?

时间:2020-03-05 18:44:19  来源:igfitidea点击:

我有一个简单的Web服务操作,如下所示:

[WebMethod]
    public string HelloWorld()
    {
        throw new Exception("HelloWorldException");
        return "Hello World";
    }

然后,我有一个使用Web服务的客户端应用程序,然后调用该操作。显然它将引发异常:-)

try
    {
        hwservicens.Service1 service1 = new hwservicens.Service1();
        service1.HelloWorld();
    }
    catch(Exception e)
    {
        Console.WriteLine(e.ToString());
    }

在我的catch块中,我想做的是提取实际异常的消息以在我的代码中使用它。捕获的异常是一个" SoapException",这很好,但是它的" Message"属性就是这样。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Exception: HelloWorldException
   at WebService1.Service1.HelloWorld() in C:\svnroot\Vordur\WebService1\Service1.asmx.cs:line 27
   --- End of inner exception stack trace ---

...而" InnerException"为" null"。

我想做的是提取InnerException的Message属性(示例中的HelloWorldException文本),有人可以帮忙吗?如果可以避免,请不要建议解析SoapException的Message属性。

解决方案

回答

不幸的是,我认为这是不可能的。

我们在Web服务代码中引发的异常被编码为Soap Fault,然后作为字符串传递回客户代码。

我们在SoapException消息中看到的只是来自Soap故障的文本,该文本不会转换回异常,而只是存储为文本。

如果要在错误情况下返回有用的信息,则建议从Web服务返回一个自定义类,该类可以具有包含信息的"错误"属性。

[WebMethod]
public ResponseClass HelloWorld()
{
  ResponseClass c = new ResponseClass();
  try 
  {
    throw new Exception("Exception Text");
    // The following would be returned on a success
    c.WasError = false;
    c.ReturnValue = "Hello World";
  }
  catch(Exception e)
  {
    c.WasError = true;
    c.ErrorMessage = e.Message;
    return c;
  }
}

回答

我前几天遇到了类似的事情,并在博客上发表了文章。我不确定它是否确切适用,但可能会适用。一旦意识到必须通过MessageFault对象,该代码就足够简单了。就我而言,我知道细节包含一个GUID,可用来重新查询SOAP服务以获取细节。代码如下:

catch (FaultException soapEx)
{
    MessageFault mf = soapEx.CreateMessageFault();
    if (mf.HasDetail)
    {
        XmlDictionaryReader reader = mf.GetReaderAtDetailContents();
        Guid g = reader.ReadContentAsGuid();
    }
}