C# Web 服务客户端:具有相同(复杂)返回类型的多个 Web 服务方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/580042/
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
C# web-service client: multiple web-service methods with same (complex) return type?
提问by Bernard
I am chipping away at building a client for a Java B2B web-service at the moment and I think I have identified the cause of a problem we have been having for quite some time. Unfortunately I'm unable to post the WSDL.
我目前正在努力为 Java B2B Web 服务构建客户端,我想我已经确定了我们已经有一段时间了的问题的原因。不幸的是,我无法发布 WSDL。
Apparently my auto-generated proxy code (via wsdl.exe: have to use WSE 3.0 due to WCF not supporting password digest) is not able to handle the web-service's WSDL having multiple web-methods with the same complex return type.
显然,我自动生成的代理代码(通过 wsdl.exe:由于 WCF 不支持密码摘要而必须使用 WSE 3.0)无法处理具有多个具有相同复杂返回类型的 Web 方法的 Web 服务的 WSDL。
Take for example - a web-service that defines the following methods:
以一个定义以下方法的网络服务为例:
Public ComplexTypeX Blah();
Public ComplexTypeX Blue();
Public ComplexTypeX Foo();
Public ComplexTypeY Bar();
In my Reference.cs file, if I comment out all code that calls any two of Blah(), Blue() or Foo(), then the remaining uncommented method can be called no problem. However, if I have more than one of these three methods not commented out (say, Blah() and Foo()), then I get the following error message upon instantiationof the web-service client code:
在我的 Reference.cs 文件中,如果我将所有调用 Blah()、Blue() 或 Foo() 中任意两个的代码都注释掉,那么剩下的未注释的方法也可以调用没问题。但是,如果这三种方法中的一种以上没有被注释掉(比如 Blah() 和 Foo()),那么在实例化Web 服务客户端代码时我会收到以下错误消息:
"Method Blah can not be reflected." "The XML element 'ComplexTypeX' from namespace 'http://some.url' references a method and a type. Change the method's message name using WebMethodAttribute or change the type's root element using the XmlRootAttribute."
“方法废话无法体现。” “来自命名空间‘ http://some.url’的 XML 元素‘ComplexTypeX’引用了一个方法和一个类型。使用 WebMethodAttribute 更改方法的消息名称或使用 XmlRootAttribute 更改类型的根元素。”
Now, there is definitely no ComplexTypeX
method defined as part of the web-service, so I can only assume that .NET (or at least wsdl.exe) does not allow you to use a web-service that returns complex (user-defined) types of the same type across multiple methods ... right?
现在,肯定没有ComplexTypeX
方法定义为 web 服务的一部分,所以我只能假设 .NET(或至少 wsdl.exe)不允许您使用返回复杂(用户定义)的 web 服务跨多个方法的相同类型的类型......对吗?
回答by matt b
so I can only assume that .NET (or at least wsdl.exe) does not allow you to use a web-service that returns complex (user-defined) types of the same type accross multiple methods ... right?
所以我只能假设 .NET(或至少 wsdl.exe)不允许您使用返回复杂(用户定义)类型的跨多个方法的相同类型的网络服务......对吗?
This is incorrect. Imagine how much of a pain that would be if it were true - you could only ever have one method that returns a String, one that returns a Double, one that returns SomeObject, etc... it would be a nightmare.
这是不正确的。想象一下,如果它是真的,那会是多么痛苦——你只能有一个方法返回一个字符串,一个返回一个双精度值,一个返回 SomeObject 等等......这将是一场噩梦。
I'm not very familiar with web services in .NET, but from the errors you are getting it sounds like you are having issues with the XML namespaces - perhaps there is a name collision. I'd attempt to follow the suggestion in the error message, to modify the WebMethodAttribute
.
我对 .NET 中的 Web 服务不是很熟悉,但是从您收到的错误来看,您似乎遇到了 XML 命名空间的问题 - 可能存在名称冲突。我会尝试按照错误消息中的建议修改WebMethodAttribute
.
Also in addition, if you are unable to post a piece of code/document related to the trouble you are having because of some company privacy/sensitivity issues, you should post a sanitized version that still proves your test case. Almost anything "sensitive" should be able to be boiled down to a far more simpler snippet of code that still gets your point across without betraying any sensitivities.
此外,如果您由于某些公司隐私/敏感性问题而无法发布与您遇到的问题相关的代码/文档,您应该发布仍能证明您的测试用例的经过消毒的版本。几乎所有“敏感”的东西都应该能够归结为更简单的代码片段,这些代码片段仍然可以在不泄露任何敏感性的情况下传达您的观点。
回答by Cheeso
Very odd. Normally the WSDL would provide a common type, and when compiled through wsdl.exe or svcutil.exe, you'd get a shared, common type to use across any number of methods in the same interface.
很奇怪。通常,WSDL 会提供一个通用类型,当通过 wsdl.exe 或 svcutil.exe 编译时,您将获得一个共享的通用类型,以便在同一接口中的任意数量的方法中使用。
There have been problems when referencing multiple independentWSDL's in the same app, that share an ostensibly identical type, which results in two distinct CLR types being generated. There are ways around this problem - it's fairly well known. Then there is the somewhat-related problem of mapping an existing business object to a type generated from a WSDL. Another previously explored landscape.
在同一个应用程序中引用多个独立的WSDL时会出现问题,它们共享一个表面上相同的类型,这会导致生成两种不同的 CLR 类型。有很多方法可以解决这个问题——这是众所周知的。然后是将现有业务对象映射到从 WSDL 生成的类型的一些相关问题。另一个先前探索过的景观。
But you are talking about something different.
但你说的是不同的东西。
回答by John Saunders
I just searched for "references a method and a type" and found a Connect bug report "System.InvalidOperationException: The XML element * from namespace * references a references a method and a type". In this case, there is an operation and an element with the exact same name (both local name and namespace).
我刚刚搜索了“引用方法和类型”并找到了一个 Connect 错误报告“ System.InvalidOperationException:XML 元素 * 来自命名空间 * 引用了一个方法和类型的引用”。在这种情况下,有一个操作和一个具有完全相同名称(本地名称和命名空间)的元素。
It's worth noting part of the response from Microsoft:
值得注意的是微软的部分回应:
We're no longer making enhancements to ASMX; we continue to support its existing functionality, but where possible, we recommend using WCF instead.
我们不再对 ASMX 进行增强;我们继续支持其现有功能,但在可能的情况下,我们建议改用 WCF。
回答by John Saunders
Use WSDL.exe has a switch /sharetypes. This should take care of the issue.
使用 WSDL.exe 有一个开关 /sharetypes。这应该解决这个问题。
Moreover I would not agree that its a Microsoft thing as same classes are exposed as different complex types sitting in multiple wsdl. Thats not a good abstracted design.
此外,我不同意它是 Microsoft 的事情,因为相同的类被暴露为位于多个 wsdl 中的不同复杂类型。那不是一个好的抽象设计。
Ready Reference Microsoft Documentation for sharetypesTurns on type sharing feature. This feature creates one code file with a single type definition for identical types shared between different services (namespace, name and wire signature must be identical). Reference the services with http:// URLs as command-line parameters or create a discomap document for local files.
共享类型的就绪参考 Microsoft 文档打开类型共享功能。此功能为不同服务之间共享的相同类型创建一个具有单一类型定义的代码文件(命名空间、名称和线签名必须相同)。使用 http:// URL 作为命令行参数引用服务或为本地文件创建 discomap 文档。
回答by Ryan Morlok
I ran into a similar problem, and here is what I found:
我遇到了类似的问题,这是我发现的:
I had defined a complex type to return as a response:
我定义了一个复杂类型作为响应返回:
public class FooResponse {...}
[WebMethod]
public FooResponse Foo() {...}
Note that here the exact name pairing of Foo/Foo+Response is important. When I changed the method name as follows, the problem went away:
请注意,此处 Foo/Foo+Response 的确切名称配对很重要。当我如下更改方法名称时,问题就消失了:
public class FooResponse {...}
[WebMethod]
public FooResponse Fooxxx() {...}
What I believe is happening is .NET is attempting to automatically wrap the response coming from the Foo method with an element named FooResponse. The use of that same name as the object you want to return creates ambiguity. Try changing the name of your response object, or the name of your method to avoid this collision.
我相信正在发生的是 .NET 正在尝试使用名为 FooResponse 的元素自动包装来自 Foo 方法的响应。使用与您要返回的对象相同的名称会产生歧义。尝试更改响应对象的名称或方法的名称以避免这种冲突。
回答by Seraphim's
I found another case that raise the error! Here's my code:
我发现了另一个引发错误的案例!这是我的代码:
[WebMethod]
public CheckUpdateResponse CheckUpdate()
{
...
}
Ok, let me explain: the return type CheckUpdateResponse
is a structure, CheckUpdate()
is the method. So, in the WSDL .NET add automatically a "Response
" suffix to the method name CheckUpdate
in one of the XML element to describe the return value of the method.
好吧,让我解释一下:返回类型CheckUpdateResponse
是结构,CheckUpdate()
是方法。因此,在 WSDL .NET中,在 XML 元素之一中的方法名称后自动添加一个“ Response
”后缀CheckUpdate
来描述方法的返回值。
Et voilà: it found a duplicate element and give the error "Change the method's message name using WebMethodAttribute..."
等等:它发现了一个重复的元素并给出错误“使用 WebMethodAttribute 更改方法的消息名称...”
Solution? I renamed the return type to "CheckUpdateResult" and now everything works well!
解决方案?我将返回类型重命名为“CheckUpdateResult”,现在一切正常!
I hope this will help someone!
我希望这会帮助某人!