如何从 ASP.NET 中的肥皂异常中提取内部异常?
-
09-06-2019 - |
题
我有一个简单的网络服务操作,如下所示:
[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
.
我想做的是提取 Message
的财产 InnerException
(这 HelloWorldException
我的示例中的文本),任何人都可以帮忙吗?如果可以避免,请不要建议解析 Message
的财产 SoapException
.
解决方案
不幸的是我认为这是不可能的。
您在 Web 服务代码中引发的异常被编码为 Soap 错误,然后将其作为字符串传递回客户端代码。
您在 SoapException 消息中看到的只是来自 Soap 错误的文本,它不会转换回异常,而只是存储为文本。
如果您想在错误情况下返回有用的信息,那么我建议您从 Web 服务返回一个自定义类,该类可以具有包含您的信息的“Error”属性。
[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;
}
}
其他提示
它 是 可能的!
服务操作示例:
try
{
// do something good for humanity
}
catch (Exception e)
{
throw new SoapException(e.InnerException.Message,
SoapException.ServerFaultCode);
}
消费服务的客户端:
try
{
// save humanity
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
只有一件事 - 您需要在 web.config 中设置 customErrors mode='RemoteOnly' 或 'On' (服务项目)。
有关 customErrors 发现的积分 - http://forums.asp.net/t/236665.aspx/1
我不久前遇到过类似的事情 在博客上谈论了它. 。我不确定它是否完全适用,但可能是。一旦您意识到必须遍历 MessageFault 对象,代码就足够简单了。就我而言,我知道详细信息包含一个 GUID,我可以使用它来重新查询 SOAP 服务以获取详细信息。代码如下所示:
catch (FaultException soapEx)
{
MessageFault mf = soapEx.CreateMessageFault();
if (mf.HasDetail)
{
XmlDictionaryReader reader = mf.GetReaderAtDetailContents();
Guid g = reader.ReadContentAsGuid();
}
}