【问题标题】:A change in namespace prefix now returns null in WCF response命名空间前缀的更改现在在 WCF 响应中返回 null
【发布时间】:2022-01-22 06:11:21
【问题描述】:

几年前,我使用 VS2015 从 C# 中的 wsdl 生成了一个 wcf 代理。 供应商已通知我响应合同已更改。他们删除了命名空间的前缀,如下所示(注意两个地方):

之前:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:Encoding="http://schemas.xmlsoap.org/soap/encoding/">
 <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <toto:ExportDataResponse xmlns:toto="company">
        <Data>blahblahblah</Data>
    </toto:ExportDataResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

之后:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
                   xmlns:Encoding="http://schemas.xmlsoap.org/soap/encoding/">
 <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <ExportDataResponse xmlns="company">
          <Data>blahblahblah</Data>
      </ExportDataResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我执行了搜索以查找前缀,但我不确定它的指定位置。是在wsdl文件中还是在生成的Reference.cs文件中?

然后我继续使用新服务器的 wsdl 更新我的服务引用。 当我将 Reference.cs 与其以前的版本进行比较时,我注意到生成的代码没有改变(可能是我正在使用的“新”wsdl 没有更新以反映这些变化吗?这可能吗?)。

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(WrapperName="ExportDataResponse", WrapperNamespace="company", IsWrapped=true)]
public partial class CompanyWS_Out {
    
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="", Order=0)]
    public string Data;
    
    public CompanyWS_Out() {
    }
    
    public CompanyWS_Out(string Data) {
        this.Data = Data;
    }
}

虽然文件没有改变,但我可以看到,如果我使用的是旧服务器(使用旧版本的服务),Data 字段实际上是值,而如果我使用的是新服务器(使用新版本没有前缀的服务),Data 为空。

我不确定如何继续或从哪里开始解决此问题。 我认为这就像更新服务引用或在生成的代码中查找前缀并将其删除一样简单。

非常感谢任何帮助。谢谢。

【问题讨论】:

  • 你的代码中是否有IDispatchMessageInspector类,你可以看看this post
  • @LanHuang 这让我找到了正确的解决方案。谢谢你。虽然我改用 IClientMessageInspector 因为我需要更改来自客户端的传入响应。

标签: c# wcf soap


【解决方案1】:

我最终实现了 IClientMessageInspector 并更改了来自客户端的传入响应。

大量灵感来自this post,谢谢@LanHuang。

public class CorrectorInspector : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message request, object correlationState)
        {
            request = FilterMessage(request);
        }

        public object BeforeSendRequest(ref Message reply, IClientChannel channel)
        {
            return null;
        }

        private Message FilterMessage(Message originalMessage)
        {
            MemoryStream memoryStream = new MemoryStream();
            XmlWriter xmlWriter = XmlWriter.Create(memoryStream);
            originalMessage.WriteMessage(xmlWriter);
            xmlWriter.Flush();
            string body = Encoding.UTF8.GetString(memoryStream.ToArray());
            xmlWriter.Close();

            body = body.Replace("ExportDataResponse", "toto:ExportDataResponse");
            body = body.Replace("xmlns=\"company\"", "xmlns:toto=\"company\"");

            memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
            XmlDictionaryReader xmlDictionaryReader = XmlDictionaryReader.CreateTextReader(memoryStream, XmlDictionaryReaderQuotas.Max);
            Message newMessage = Message.CreateMessage(xmlDictionaryReader, int.MaxValue, originalMessage.Version);

            //memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
            //XmlReader reader = XmlReader.Create(memoryStream);
            //Message newMessage = Message.CreateMessage(reader, int.MaxValue, originalMessage.Version);

            newMessage.Properties.CopyProperties(originalMessage.Properties);
            return newMessage;
        }
    }

【讨论】:

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