C# WCF 服务 - 向后兼容性问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WCF Service - Backward compatibility issue
提问by ZombieSheep
I'm just getting into creating some WCF services, but I have a requirement to make them backward compatible for legacy (.NET 1.1 and 2.0) client applications.
我刚刚开始创建一些 WCF 服务,但我需要使它们向后兼容旧版(.NET 1.1 和 2.0)客户端应用程序。
I've managed to get the services to run correctly for 3.0 and greater clients, but when I publish the services using a basicHttpBinding endpoint (which I believe is required for the compatibility I need), the service refactors my method signatures. e.g.
我已经设法让服务为 3.0 和更高版本的客户端正确运行,但是当我使用 basicHttpBinding 端点(我认为这是我需要的兼容性所必需的)发布服务时,该服务重构了我的方法签名。例如
public bool MethodToReturnTrue(string seedValue);
appears to the client apps as
在客户端应用程序中显示为
public void MethodToReturnTrue(string seedValue, out bool result, out bool MethodToReturnTrueResultSpecified);
I've tried every configuration parameter I can think of in the app.config for my self-hosting console app, but I can't seem to make this function as expected. I suppose this might lead to the fact that my expectations are flawed, but I'd be surprised that a WCF service is incapable of handling a bool return type to a down-level client.
我已经在 app.config 中为我的自托管控制台应用程序尝试了我能想到的所有配置参数,但我似乎无法按预期实现此功能。我想这可能会导致我的期望是有缺陷的,但我会惊讶的是 WCF 服务无法处理下级客户端的 bool 返回类型。
My current app.config looks like this.
我当前的 app.config 看起来像这样。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="MyServiceTypeBehaviors" Name="MyCompany.Services.CentreService.CentreService">
<clear />
<endpoint address="http://localhost:8080/CSMEX" binding="basicHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
<endpoint address="http://localhost:8080/CentreService" binding="basicHttpBinding" bindingName="Compatible" name="basicEndpoint" contract="MyCompany.Services.CentreService.ICentreService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Can anyone advise, please?
请问有人可以建议吗?
采纳答案by ZombieSheep
OK, we needed to resolve this issue in the short term, and so we came up with the idea of a "interop", or compatibility layer.
好的,我们需要在短期内解决这个问题,因此我们提出了“互操作”或兼容层的想法。
Baiscally, all we did was added a traditional ASMX web service to the project, and called the WCF service from that using native WCF calls. We were then able to return the appropriate types back to the client applications without a significant amount of re-factoring work. I know it was a hacky solution, but it was the best option we had with such a large legacy code-base. And the added bonus is that it actually works surprisingly well. :)
Baiscally,我们所做的只是在项目中添加了一个传统的 ASMX Web 服务,并使用本机 WCF 调用从该服务中调用 WCF 服务。然后,我们能够将适当的类型返回给客户端应用程序,而无需进行大量的重构工作。我知道这是一个笨拙的解决方案,但它是我们拥有如此庞大的遗留代码库的最佳选择。额外的好处是它实际上运行得非常好。:)
回答by Esteban Araya
Ah, this is killing me! I did this at work about 3 months ago, and now I can't remember all the details.
啊,这是要了我的命!大约 3 个月前我在工作中做过这个,现在我不记得所有的细节了。
I do remember, however, that you need basicHttpBinding, and you can't use the new serializer (which is the default); you have to use the "old" XmlSerializer.
但是,我确实记得您需要 basicHttpBinding,并且您不能使用新的序列化程序(这是默认设置);你必须使用“旧的”XmlSerializer。
Unfortunately, I don't work at the place where I did this anymore, so I can't go look at the code. I'll call my boss and see what I can dig up.
不幸的是,我不再在我这样做的地方工作了,所以我不能去看代码。我会打电话给我的老板,看看我能挖掘出什么。
回答by Christian Hayter
You do have to use the XmlSerializer. For example:
您必须使用 XmlSerializer。例如:
[ServiceContract(Namespace="CentreServiceNamespace")]
[XmlSerializerFormat(Style=OperationFormatStyle.Document, SupportFaults=true, Use=OperationFormatUse.Literal)]
public interface ICentreService {
[OperationContract(Action="CentreServiceNamespace/MethodToReturnTrue")]
bool MethodToReturnTrue(string seedValue);
}
You have to manually set the operation action name because the auto-generated WCF name is constructed differently from the ASMX action name (WCF includes the interface name as well, ASMX does not).
您必须手动设置操作操作名称,因为自动生成的 WCF 名称的构造与 ASMX 操作名称不同(WCF 也包含接口名称,ASMX 不包含)。
Any data contracts you use should be decorated with [XmlType]
rather than [DataContract]
.
您使用的任何数据协定都应该用[XmlType]
而非装饰[DataContract]
。
Your config file should not need to change.
您的配置文件应该不需要更改。