【发布时间】: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
【问题讨论】: