You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core无SoapException时,如何获取WCF服务的异常XML?

在.NET Core中捕获SOAP服务异常并读取异常XML

原问题:在.NET Framework中,我可通过以下代码捕获SoapException并读取异常XML:

try { 
  // soap call here 
} catch (System.Web.Services.Protocols.SoapException soapEx) { 
  var msg = soapEx.Message; 
  var txt = soapEx.Detail.InnerText; 
}

在.NET Core中,我使用svcutil将WSDL生成代码,通过编程方式构建EndpointAddress和BasicHttpsBinding调用客户端,但无法访问SoapException,请问该如何获取异常XML?

解决方案

在.NET Core/.NET 5+生态里,System.Web.Services.Protocols.SoapException已经被移除了,不过我们有两种常用的方式来获取SOAP异常的XML内容,亲测好用:

方法1:捕获FaultException解析异常细节

svcutil生成的客户端会把服务抛出的SOAP Fault包装成FaultException(如果服务定义了强类型错误详情,就是FaultException<T>),你可以通过它来获取消息和XML细节:

try
{
    // 初始化你的SOAP客户端并调用方法
    var binding = new BasicHttpsBinding();
    var endpoint = new EndpointAddress("你的服务地址");
    using var client = new GeneratedSoapClient(binding, endpoint);
    
    await client.YourServiceOperationAsync();
}
catch (FaultException faultEx)
{
    // 获取Fault的提示消息
    var errorMessage = faultEx.Message;
    
    // 读取SOAP Fault里的Detail节点XML
    var messageFault = faultEx.CreateMessageFault();
    if (messageFault.HasDetail)
    {
        var detailXml = messageFault.GetReaderAtDetailContents().ReadOuterXml();
        // 这里就拿到了异常的XML内容,按需处理即可
    }
}
catch (FaultException<YourDefinedFaultType> typedFault)
{
    // 如果服务有定义强类型的错误对象,直接用这个泛型捕获,更方便
    var faultDetail = typedFault.Detail;
    // 可以直接访问faultDetail的属性,不用手动解析XML
}

方法2:用消息拦截器获取完整SOAP响应

如果需要拿到完整的原始SOAP响应XML(包括整个Envelope结构),可以自定义一个客户端消息拦截器来捕获响应内容:

  1. 先实现IClientMessageInspector来保存响应:
public class SoapResponseCaptureInspector : IClientMessageInspector
{
    public string RawSoapResponse { get; private set; }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return null; // 不需要处理请求,返回null即可
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        // 把响应消息复制一份,避免影响后续处理
        var messageBuffer = reply.CreateBufferedCopy(int.MaxValue);
        // 将消息转为字符串,就是完整的SOAP XML
        RawSoapResponse = messageBuffer.CreateMessage().ToString();
        // 重置消息,让客户端能正常处理后续流程
        reply = messageBuffer.CreateMessage();
    }
}
  1. 再创建一个行为类把拦截器加到客户端上:
public class SoapResponseCaptureBehavior : IEndpointBehavior
{
    private readonly SoapResponseCaptureInspector _inspector;

    public SoapResponseCaptureBehavior(SoapResponseCaptureInspector inspector)
    {
        _inspector = inspector;
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        // 把拦截器添加到客户端的消息检查器列表里
        clientRuntime.ClientMessageInspectors.Add(_inspector);
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

    public void Validate(ServiceEndpoint endpoint) { }
}
  1. 最后在客户端里使用这个拦截器:
var responseInspector = new SoapResponseCaptureInspector();
var binding = new BasicHttpsBinding();
var endpoint = new EndpointAddress("你的服务地址");

using var client = new GeneratedSoapClient(binding, endpoint);
// 把自定义行为添加到客户端的Endpoint上
client.Endpoint.Behaviors.Add(new SoapResponseCaptureBehavior(responseInspector));

try
{
    await client.YourServiceOperationAsync();
}
catch (Exception)
{
    // 不管是什么异常,都能拿到完整的SOAP响应XML
    var fullSoapXml = responseInspector.RawSoapResponse;
    // 解析这个XML就能拿到所有异常信息了
}

小提示

  • 如果服务返回的是标准的SOAP Fault,用FaultException的方式足够,代码更简洁。
  • 拦截器方式适合调试场景,或者需要处理非标准Fault的情况,能拿到最原始的响应内容。

内容的提问来源于stack exchange,提问作者aherrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:24:22