【问题标题】:Empty message <s:Body/> while calling WCF service调用 WCF 服务时的空消息 <s:Body/>
【发布时间】:2014-07-14 14:09:36
【问题描述】:

所以,我有这组第三方 Web 服务,我已经使用了一段时间,没有遇到太多麻烦,但突然有了一个新服务,我遇到了这个问题,它一直给我一些奇怪的响应。

检查日志后,WCF 消息体似乎生成为空:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">urn:mediate</Action>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink"></VsDebuggerCausalityData>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"></s:Body>
</s:Envelope>

我像往常一样从代码中调用服务:

Dim nieobecnosc As SIMPLEWSProxy.nieobecnosc_TYPE = New SIMPLEWSProxy.nieobecnosc_TYPE()

nieobecnosc.wniosek_id = "8"
nieobecnosc.pracownik_nrewid = 100019
nieobecnosc.nieobecnosc_kod = "W"
nieobecnosc.data_od = "2014-10-21"
nieobecnosc.data_do = "2014-10-25"

Dim request As SIMPLEAbsenceCreateConnect.mediateRequest = New SIMPLEAbsenceCreateConnect.mediateRequest(nieobecnosc)

Dim proxy As SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortTypeClient = New SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortTypeClient("AbsenceCreateProxyHttpsSoap11Endpoint")

proxy.ClientCredentials.UserName.UserName = "MyUsername"
proxy.ClientCredentials.UserName.Password = "MyPassword"

Dim proxyCallable As SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortType = proxy

Dim response As System.ServiceModel.Channels.Message = proxyCallable.mediate(request)

Webservice 的 wsdl 是这样的:

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:tns="http://ws.apache.org/axis2" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://ws.apache.org/axis2">
   <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UTOverTransport">
      <wsp:ExactlyOne>
         <wsp:All>
            <sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
               <wsp:Policy>
                  <sp:TransportToken>
                     <wsp:Policy>
                        <sp:HttpsToken RequireClientCertificate="false"/>
                     </wsp:Policy>
                  </sp:TransportToken>
                  <sp:AlgorithmSuite>
                     <wsp:Policy>
                        <sp:Basic256/>
                     </wsp:Policy>
                  </sp:AlgorithmSuite>
                  <sp:Layout>
                     <wsp:Policy>
                        <sp:Lax/>
                     </wsp:Policy>
                  </sp:Layout>
                  <sp:IncludeTimestamp/>
               </wsp:Policy>
            </sp:TransportBinding>
            <sp:SignedSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
               <wsp:Policy>
                  <sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"/>
               </wsp:Policy>
            </sp:SignedSupportingTokens>
         </wsp:All>
      </wsp:ExactlyOne>
   </wsp:Policy>
   <wsdl:types/>
   <wsdl:message name="in"/>
   <wsdl:message name="out"/>
   <wsdl:portType name="AbsenceCreateProxyPortType">
      <wsdl:operation name="mediate">
         <wsdl:input message="tns:in" wsaw:Action="urn:mediate"/>
         <wsdl:output message="tns:out" wsaw:Action="urn:mediateResponse"/>
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="AbsenceCreateProxySoap11Binding" type="tns:AbsenceCreateProxyPortType">
      <wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" URI="#UTOverTransport"/>
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
      <wsdl:operation name="mediate">
         <soap:operation soapAction="urn:mediate" style="document"/>
         <wsdl:input>
            <soap:body use="literal"/>
         </wsdl:input>
         <wsdl:output>
            <soap:body use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:binding name="AbsenceCreateProxySoap12Binding" type="tns:AbsenceCreateProxyPortType">
      <wsp:PolicyReference xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" URI="#UTOverTransport"/>
      <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
      <wsdl:operation name="mediate">
         <soap12:operation soapAction="urn:mediate" style="document"/>
         <wsdl:input>
            <soap12:body use="literal"/>
         </wsdl:input>
         <wsdl:output>
            <soap12:body use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:binding name="AbsenceCreateProxyHttpBinding" type="tns:AbsenceCreateProxyPortType">
      <http:binding verb="POST"/>
      <wsdl:operation name="mediate">
         <http:operation location="mediate"/>
         <wsdl:input>
            <mime:content type="text/xml" part="parameters"/>
         </wsdl:input>
         <wsdl:output>
            <mime:content type="text/xml" part="parameters"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="AbsenceCreateProxy">
      <wsdl:port name="AbsenceCreateProxyHttpsSoap11Endpoint" binding="tns:AbsenceCreateProxySoap11Binding">
         <soap:address location="https://192.168.1.3:8243/services/AbsenceCreateProxy.AbsenceCreateProxyHttpsSoap11Endpoint"/>
      </wsdl:port>
      <wsdl:port name="AbsenceCreateProxyHttpsSoap12Endpoint" binding="tns:AbsenceCreateProxySoap12Binding">
         <soap12:address location="https://192.168.1.3:8243/services/AbsenceCreateProxy.AbsenceCreateProxyHttpsSoap12Endpoint"/>
      </wsdl:port>
      <wsdl:port name="AbsenceCreateProxyHttpsEndpoint" binding="tns:AbsenceCreateProxyHttpBinding">
         <http:address location="https://192.168.1.3:8243/services/AbsenceCreateProxy.AbsenceCreateProxyHttpsEndpoint"/>
      </wsdl:port>
   </wsdl:service>

我不是网络服务方面的专家,老实说,我不知道如何开始寻找潜在问题,因为我无法访问服务本身。

有什么想法吗?

谢谢,巴特克

编辑:用一些额外的信息更新了我的问题,因为它可能是相关的。

通常,当我从为类似服务提供的 wsdls 自动生成代码时,生成的类最初看起来像这样(为了清楚起见,删除了不相关的代码):

Namespace SIMPLEAbsenceCreateConnect

    Public Interface AbsenceCreateProxyPortType
        Function mediate(ByVal request As SIMPLEAbsenceCreateConnect.mediateRequest) As SIMPLEAbsenceCreateConnect.mediateResponse
    End Interface

    Partial Public Class mediateRequest

        Public Sub New()
            MyBase.New()
        End Sub
    End Class

    Partial Public Class mediateResponse

        Public Sub New()
            MyBase.New()
        End Sub
    End Class

    Public Interface AbsenceCreateProxyPortTypeChannel
        Inherits SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortType, System.ServiceModel.IClientChannel
    End Interface

    Partial Public Class AbsenceCreateProxyPortTypeClient
        Inherits System.ServiceModel.ClientBase(Of SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortType)
        Implements SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortType

        Public Sub New()
            MyBase.New()
        End Sub

        <System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)> _
        Function SIMPLEAbsenceCreateConnect_AbsenceCreateProxyPortType_mediate(ByVal request As SIMPLEAbsenceCreateConnect.mediateRequest) As SIMPLEAbsenceCreateConnect.mediateResponse Implements SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortType.mediate
            Return MyBase.Channel.mediate(request)
        End Function

        Public Sub mediate()
            Dim inValue As SIMPLEAbsenceCreateConnect.mediateRequest = New SIMPLEAbsenceCreateConnect.mediateRequest()
            Dim retVal As SIMPLEAbsenceCreateConnect.mediateResponse = CType(Me, SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortType).mediate(inValue)
        End Sub
    End Class
End Namespace

但是这段代码有问题:mediateRequest 和 mediateResponse 类是空的。

为了解决这个问题,我正在修改 mediateRequest 类,因此它可以包含需要发送的实际请求数据:

Partial Public Class mediateRequest

    Public nieobecnosc As SIMPLEWSProxy.nieobecnosc_TYPE

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal A_nieobecnosc As SIMPLEWSProxy.nieobecnosc_TYPE)
        MyBase.New()
        Me.nieobecnosc = A_nieobecnosc
    End Sub

End Class

在此更改标准调用之后:

Dim response As SIMPLEAbsenceCreateConnect.mediateResponse = proxyCallable.mediate(request)

抛出异常:

命名空间中的结束元素“Body” 'http://schemas.xmlsoap.org/soap/envelope/' 预期。找到的元素 来自命名空间''的'响应'

我通常的解决方法是修改 SIMPLEAbsenceCreateConnect_AbsenceCreateProxyPortType_mediate() 函数以返回 System.ServiceModel.Channels.Message 类型,而不是 mediateResponse,这可能是一种不好的方法,但它适用于我的应用程序中的所有其他 Web 服务。

Function SIMPLEAbsenceCreateConnect_AbsenceCreateProxyPortType_mediate(ByVal request As SIMPLEAbsenceCreateConnect.mediateRequest) As System.ServiceModel.Channels.Message Implements SIMPLEAbsenceCreateConnect.AbsenceCreateProxyPortType.mediate
    Return MyBase.Channel.mediate(request)
End Function

【问题讨论】:

    标签: vb.net wcf


    【解决方案1】:

    试试:

    Dim response As SIMPLEAbsenceCreateConnect.mediateResponse = proxyCallable.mediate(request)
    

    并检查身体

    【讨论】:

    • 不幸的是,之前尝试过但没有成功,消息正文为空。用一些额外的信息更新了我的问题,澄清了我到目前为止所做的事情。
    【解决方案2】:

    好的,我终于成功了!

    我觉得自己很笨。我在 mediateRequest 中的 nieobecnosc 属性应该这样声明:

    <System.ServiceModel.MessageBodyMemberAttribute(Namespace:="http://www.simple.com.pl/SimpleErp", Order:=0)> _
    Public nieobecnosc As SIMPLEWSProxy.nieobecnosc_TYPE
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      相关资源
      最近更新 更多