我们正在连接到一个Web服务,我们收到的错误消息没有反序列化(根本没有),并且我可以制作的类的任何版本都不会正确反序列化。我们无法控制服务器方面的事情。服务器不允许发现,因此将?WSDL添加到端点的URL末尾会导致错误,而不是WSDL。

[Fiddler] [1]显示回来的故障信息如下:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:eGov="http://eGov.gov" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <soapenv:Fault>
    <faultcode>Client</faultcode>
    <faultstring/>
      <detail>
        <eGov:eGov2Exception>
          <eGov:ErrorClassification>SOME_ERROR</eGov:ErrorClassification>
          <eGov:ErrorCode>SOME_ERROR_CODE</eGov:ErrorCode>
          <eGov:ErrorMessage>Your request was unsuccessful. blah blah blah.</eGov:ErrorMessage>
        </eGov:eGov2Exception>
      </detail>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>

然而,我们没有做过的类(尝试xsd.exe,svcutil和其他包括我们从头开始编写的代码)可以在我们尝试捕获它时反序列化它:

catch (FaultException<eGov2ExceptionType> exp)
  {
     // Never stops here. 
  }
catch (FaultException<AllOtherAttemptedClasses> exp)
  {
     // Never stops here. 
  }
catch (SoapException se)
  {
     // Never stops here. 
  }
catch (FaultException exp)
  {
     //Always gets caught here. 
  }

只会调用基本的FaultException catch,这意味着我们将丢失正在发送的FaultMessage的内容。我编写的一些类将与上面的示例非常接近地序列化,但是无法对其进行反序列化,因此我们怀疑存在名称空间问题。

问题:

1 - 你会怎么写这个?

2 - 这是WCF的常见错误/问题吗?

[1]: http://www.fiddler2.com/fiddler2/ Fiddler

有帮助吗?

解决方案

我们最终做的是放弃尝试捕获 Fault 并将其传回SOAP通道。相反,我们创建了一个自定义异常,并连接了一个 MessageInspector 来监视错误并将其作为异常抛出。

(已消毒)代码的相关部分:

   public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        if (reply.IsFault)
        {
            XmlDictionaryReader xdr = reply.GetReaderAtBodyContents();
            XNode xn = XDocument.ReadFrom(xdr);
            string s = xn.ToString();
            XDocument xd = XDocument.Parse(s);
            XNamespace nsSoap = "http://schemas.xmlsoap.org/soap/envelope/";
            XNamespace ns = "http://eGov.gov";
            XElement xErrorClass = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorClassification");
            XElement xErrorCode = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorCode");
            XElement xErrorMessage = xd.Element(nsSoap + "Fault").Element("detail").Element(ns + "eGov2Exception").Element(ns + "RequestErrorMessage");

            throw new eGovException(xErrorClass.Value, xErrorCode.Value, xErrorMessage.Value);
        }
    }

然后主应用程序使用:

catch(eGovException ex)
  {点击     //在这里处理异常。
  }

试图纠正名称空间浪费了太多时间。谢谢回答。

其他提示

如果序列化完全失败,处理此问题的一种方法是使用消息类型作为输入和输出。这样,您可以在Iffault == true时手动解析XML,或者如果没有错误发生,则使用GetBody()获取常规内容。

首先,如果您无法从生成此Web服务的人那里获得WSDL,那么他们就没有基于SOAP的Web服务的业务。正确的WSDL将解决您的问题,无论是否<!>“?WSDL <!>”;使用。

其次,请发布eGov2ExceptionType类的代码。我怀疑它没有设置http://eGov.gov命名空间。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top