WCF为什么有时在生成的代理类型末尾添加“Field”?

17

基本上,我有一个名为“Foo”的服务器端类型,其成员为X和Y。 每当我使用Visual Studio的“添加服务器引用”功能时,我会看到WSDL和生成的代理都在所有成员后追加“Field”一词,并更改第一个字母的大小写。 也就是说,“X”和“Y”被重命名为“xField”和“yField”。 有任何想法为什么会发生这种情况吗? 我无法找出规律。

详细信息--我有一个遗留的ASMX Web服务,它公开了一个“Foo”类型。 我创建了一个新的WCF服务,它是旧Web服务的包装器--新服务只是包装那些方法并可能更新一些字段的值,但它公开了完全相同的方法并返回完全相同的类型。 我尝试重新创建引用多次,每次它总是重命名我的字段:变量“STUFF”在wsdl和代理中公开为“sTUFFField”。 变量“X”公开为“xField”,等等。

有趣的是,我无法找出规律--我尝试创建一个新的ASMX Web服务作为测试并将其包装--然后不会重命名变量。 因此,我无法找出WCF何时/为什么会重命名变量的模式。

有人知道吗?


有关编程的内容:这重要吗?如果重要,那么它为什么重要? - John Saunders
2
很重要。我有两个用例(针对内部和外部用户)。内部用户可以绕过我的包装器服务,直接访问底层的遗留服务(从而绕过登录的需要)。外部用户必须通过包装器服务并提供密码等信息。但由于内部和外部服务现在给字段命名不同,我无法共享相同的代码以与两个服务通信。我需要为每个服务编写不同版本的代码。 - tavistmorph
5个回答

26

我遇到了同样的问题,sergiosp的答案让我朝着正确的方向前进。只是添加了一些额外的信息,希望能帮助其他人。

[System.ServiceModel.XmlSerializerFormatAttribute()]添加到接口中,并重新生成客户端代码,解决了我的问题。

public interface IMyService
{
    [System.ServiceModel.XmlSerializerFormatAttribute()]
    [System.ServiceModel.OperationContract]
    recordResponse GetRecord(recordRequest request);

}

谢谢你的帮助。这个代码对我也解决了问题,但是你知道它在做什么以及如何解决问题吗? - Emil
1
@batmaci 当你在Visual Studio中“添加服务引用”时,WCF会生成客户端代码来调用服务。默认情况下,它将使用DataContractSerializer。添加XmlSerializerFormatAttribute会导致WCF使用XmlSerializer生成代码。尝试先使用XmlSerializerFormatAttribute添加一次服务引用,再不添加一次,比较生成的代码文件(Reference.cs)的差异。 - tgriffin
我简直不敢相信这个答案已经搁置了2年。我在Stack Overflow和网络上疯狂搜索这个答案。这真的是我祈祷的答案。如果将来遇到同样的问题,这可能对你们有用,这里是关于构建DocuSign事件监听器以便使用其Connect通知服务的类似问题的链接。 - Mark Bailey
1
普通人如果安装了ReSharper,就会意识到有很多杂乱无章的东西。在属性中加入()是不必要的,干净的代码,常见的...所有这些杂乱无章的东西都会使事情变得混乱。 - PositiveGuy
1
我遇到了从XSD生成的类与XML序列化属性相关的问题。我不知道这是否是导致问题的原因,但我猜当类使用XML序列化时使用[XmlSerializerFormat]是有意义的。 - user247702
谢谢!我一直在尝试使用DataContract Surrogates,但它没有起作用,这个方法解决了问题! - Norman H

4

我曾经遇到过同样的问题,但是我找到了解决方法。

如果在接口中添加[DataContractFormat]标签,则会出现“XFieldField”情况。 但是,如果将其替换为[XmlSerializerFormat],则不会更改代理生成的名称。


3
通常,生成的代理将具有“XField”和“YField”作为内部/受保护/私有字段,并通过名为“X”和“Y”的属性公开值。在创建代理客户端时,您可以设置选项以调整它以符合您的喜好,我想是这样的。
更新:我似乎找不到任何开关或选项来控制此行为。这可能取决于WCF用于创建客户端代理的序列化程序(DataContractSerializer与XmlSerializer)。
最终,这实际上更多或更少只是一种编码风格问题 - 从功能上讲,它不应该有任何区别。
马克

没错,这通常是正常工作的方式,但我发现公共字段也被重命名了。因此,内部字段被称为“XFieldField”,而公共访问器被称为“XField”。这不是我想要的,这意味着包装服务的接口与实际服务的接口不同。因此,我不能再将这两个服务视为可互换的。 - tavistmorph
这很奇怪和出乎意料 - 你是在 Visual Studio 中创建客户端代理还是使用 svcutil.exe? - marc_s
确实有点奇怪和意外。这只发生在这个项目上,所以我无法找出规律。但是我是使用Visual Studio通过单击“添加服务引用”来创建客户端代理的。 - tavistmorph

0

0

我也遇到了这个问题,但是即使在接口上进行了所述的更改后,我仍然从客户端获取到类成员末尾的Field

问题在于,我正在使用DataContractSerializer来处理磁盘文件序列化请求(在测试我们的服务期间,我们从提供者那里获取序列化请求,以便在上线之前进行调试)。

DataContractSerializer更改为XmlSerializer后,通过typeof()调用指定根元素和根命名空间(因为默认情况下,XmlSerializers会写入标准命名空间),我可以反序列化请求并完美地使用WCF服务。

希望这能帮助某些人。我在这个“问题”上浪费了很多时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接