【问题标题】:WCF namespace prefixWCF 命名空间前缀
【发布时间】:2015-07-27 13:16:58
【问题描述】:

我正在尝试使用我理解为来自第三方提供商的旧式 ASMX Web 服务,但我想使用 WCF,因为这是对新式应用程序的推荐方法。

当我将服务引用作为 Web 引用添加到我的应用程序时(单击“添加服务引用”对话框中的“高级”按钮并选择“添加 Web 引用”),我可以成功使用该 Web 服务。一切正常。然而,据我了解,这是设置 Web 服务的旧式方法。

我想要通过 WCF 来完成,所以我开始添加服务引用,而不是作为 Web 引用(例如,添加服务引用对话框,输入地址并单击 Go)。我与 Web 服务对话的所有代码似乎都可以正常工作,但是我不断收到以下异常:

System.ServiceModel.CommunicationException was unhandled by user code
  HResult=-2146233087
  Message=Unrecognized message version.
  Source=mscorlib
  StackTrace:
    Server stack trace: 
       at System.ServiceModel.Channels.ReceivedMessage.ReadStartEnvelope(XmlDictionaryReader reader)
       at System.ServiceModel.Channels.BufferedMessage..ctor(IBufferedMessageData messageData, RecycledMessageState recycledMessageState, Boolean[] understoodHeaders, Boolean     understoodHeadersModified)
       at System.ServiceModel.Channels.BufferedMessage..ctor(IBufferedMessageData messageData, RecycledMessageState recycledMessageState)
       at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.ReadMessage(ArraySegment`1 buffer, BufferManager bufferManager, String contentType)
       at System.ServiceModel.Channels.MessageEncoder.ReadMessage(Stream stream, BufferManager bufferManager, Int32 maxBufferSize, String contentType)
       at System.ServiceModel.Channels.HttpInput.ReadChunkedBufferedMessage(Stream inputStream)
       at System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(HttpRequestMessage httpRequestMessage, Exception& requestException)
       at System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(Exception& requestException)
       at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
       at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
       at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    Exception rethrown at [0]: 
       at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       at MarketVision.FulfillmentService.FulfillmentProcessors.TextWire.Processor.TextWireProxy.WS_CompanyPortType.readCompany(WSAuthentication auth)
       at MarketVision.FulfillmentService.FulfillmentProcessors.TextWire.Processor.TextWireProxy.WS_CompanyPortTypeClient.readCompany(WSAuthentication auth)
       at MarketVision.FulfillmentService.FulfillmentProcessors.TextWire.Processor.ServiceAgent.CreateCompany(String name)
       at MarketVision.FulfillmentService.FulfillmentProcessors.TextWire.Processor.TextWireFulfillmentProcessor.FulfillOrders(IEnumerable`1 orders)
       at FulfillmentService.Services.Wcf.FulfillmentService.FulfillOrders(IFulfillmentInfo fulfillmentInfo) in x:\FulfillmentService\Main\Source\Services\Wcf\FulfillmentService.cs:line 18
       at SyncInvokeFulfillOrders(Object , Object[] , Object[] )
       at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
       at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
  InnerException: 

我玩过 fiddler,它看起来像是一个简单的命名空间问题,我不知道如何解决。以下是在将服务设置为 Web 参考时有效的消息:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
               xmlns:tns="urn:webservices2_0_0"
               xmlns:types="urn:webservices2_0_0/encodedTypes"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <tns:readCompany>
            <auth href="#id1" />
        </tns:readCompany>
        <tns:WSAuthentication id="id1" xsi:type="tns:WSAuthentication">
            <api_key xsi:type="xsd:string">myApiKey</api_key>
            <code xsi:type="xsd:string">myCode</code>
            <keyword xsi:type="xsd:string">myKeyword</keyword>
            <password xsi:type="xsd:string">myPassword</password>
            <username xsi:type="xsd:string">myUsername</username>
        </tns:WSAuthentication>
    </soap:Body>
</soap:Envelope>

这是一个在将服务设置为仅作为服务参考(而不是作为网络参考)时不会:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <q1:readCompany xmlns:q1="urn:webservices2_0_0">
            <auth href="#id1"/>
        </q1:readCompany>
        <q2:WSAuthentication id="id1" xsi:type="q2:WSAuthentication" xmlns:q2="urn:webservices2_0_0">
            <api_key xsi:type="xsd:string">myApiKey</api_key>
            <code xsi:type="xsd:string">myCode</code>
            <keyword xsi:type="xsd:string">myKeyword</keyword>
            <password xsi:type="xsd:string">myPassword</password>
            <username xsi:type="xsd:string">myUserName</username>
        </q2:WSAuthentication>
    </s:Body>
</s:Envelope>

除了命名空间之外,这两条消息之间显然存在差异,但我在 fiddler 中要做的就是获取不起作用的消息并将所有 s: 命名空间更改为 soap: 并且一切正常。所以,我很确定我所要做的就是改变命名空间,就像我对提琴手所做的那样,这应该可以使用 WCF,但我不知道该怎么做。

【问题讨论】:

  • 您是如何创建代理的?您使用了 svutil 还是有服务合同的 dll 文件?
  • 右键单击 Visual Studio 解决方案中的“服务引用”节点并填写“添加服务引用”对话框,提供第三方 Web 服务的 URL(我相信,它本质上是 svcutil 提供的 url,但是只是想明确说明我是如何做到的)。

标签: c# wcf


【解决方案1】:

您应该尝试使用 svcutil 命令行工具(打开一个 VS 命令提示符来运行它),它虽然类似于 VS 的参考功能,但实际上是一个完全不同的代码库。您可以使用它来生成代理、所有客户端类型等,就像使用服务引用功能一样,它非常可靠。

【讨论】:

  • 同样的结果。无法识别的消息版本异常。
猜你喜欢
  • 1970-01-01
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-20
  • 2012-05-08
  • 1970-01-01
相关资源
最近更新 更多