简体   繁体   English

命名空间前缀的更改现在在 WCF 响应中返回 null

[英]A change in namespace prefix now returns null in WCF response

I generated years ago a wcf proxy from a wsdl in C# using VS2015.几年前,我使用 VS2015 从 C# 中的 wsdl 生成了 wcf 代理。 I've been notified from the provider that the response contract has changed.供应商已通知我响应合同已更改。 They removed the prefix of the namespace as seen here (note two places):他们删除了命名空间的前缀,如下所示(注意两个地方):

Before:前:

<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>

After:后:

<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>

I performed a search looking for the prefix but I am unsure where it is specified.我执行了搜索以查找前缀,但我不确定它的指定位置。 Is it in the wsdl file or in the generated Reference.cs file?是在 wsdl 文件中还是在生成的 Reference.cs 文件中?

I then proceeded to update my service reference using the new server's wsdl.然后我继续使用新服务器的 wsdl 更新我的服务参考。 I noticed the generated code hasn't changed when I compare the Reference.cs with its previous version (could it be that the "new" wsdl that I am using hasn't been updated to reflect the changes? Is that possible?).当我将 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;
    }
}

Although the files haven't changed, I can see that if I am using the old server (with the old version of the service), the Data field actually values whereas if I am using the new server (with the new version of the service without the prefix), Data is null.虽然文件没有改变,但我可以看到,如果我使用的是旧服务器(使用旧版本的服务),Data 字段实际上是值,而如果我使用的是新服务器(使用新版本的服务)不带前缀),数据为 null。

I am uncertain how to proceed or where to even begin troubleshooting this issue.我不确定如何继续或从哪里开始解决此问题。 I thought it would be as simple as just updating the service reference or looking for the prefix in the generated code and removing it.我认为这就像更新服务引用或在生成的代码中查找前缀并将其删除一样简单。

Any help is greatly appreciated.任何帮助是极大的赞赏。 Thank you.谢谢你。

I ended up implementing IClientMessageInspector and changed the incoming response from the client side.我最终实现了 IClientMessageInspector 并更改了来自客户端的传入响应。

Heavily inspired from this post , thank you @LanHuang.这篇文章给了我很大的启发,谢谢@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;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM