C#web-service客户端:具有相同(复杂)返回类型的多个Web服务方法?

时间:2009-02-24 00:44:20

标签: c# xsd wsdl wsdl.exe

我正在努力建立一个Java B2B网络服务的客户端,我想我已经确定了一段时间以来我们遇到的问题的原因。不幸的是我无法发布WSDL。

显然我的自动生成的代理代码(通过wsdl.exe:由于WCF不支持密码摘要而必须使用WSE 3.0)无法处理具有多个具有相同复杂返回类型的Web方法的Web服务的WSDL

以例如 - 定义以下方法的Web服务:

Public ComplexTypeX Blah();
Public ComplexTypeX Blue();
Public ComplexTypeX Foo();
Public ComplexTypeY Bar();

在我的Reference.cs文件中,如果我注释掉所有调用Blah(),Blue()或Foo()中的任何两个的代码,那么剩下的未注释方法可以被调用没问题。但是,如果我没有注释掉这三个方法中的多个(例如,Blah()和Foo()),那么我在Web服务客户端代码的实例化时收到以下错误消息:

  

“方法Blah无法反映。”   “来自的XML元素'ComplexTypeX'   名称空间“http://some.url”引用   方法和类型。改变   方法的消息名称使用   WebMethodAttribute或更改   使用的类型的根元素   XmlRootAttribute“。

现在,肯定没有将ComplexTypeX方法定义为Web服务的一部分,所以我只能假设.NET(或至少wsdl.exe)不允许您使用Web服务它返回多个方法中相同类型的复杂(用户定义)类型......对吗?

6 个答案:

答案 0 :(得分:8)

我遇到了类似的问题,这就是我发现的:

我已经定义了一个复杂类型作为响应返回:

public class FooResponse {...}

[WebMethod]
public FooResponse Foo() {...}

请注意,这里Foo / Foo + Response的确切名称配对非常重要。当我按如下方式更改方法名称时,问题就消失了:

public class FooResponse {...}

[WebMethod]
public FooResponse Fooxxx() {...}

我相信正在发生的事情是.NET试图使用名为FooResponse的元素自动包装来自Foo方法的响应。使用与要返回的对象相同的名称会产生歧义。尝试更改响应对象的名称或方法名称以避免此冲突。

答案 1 :(得分:3)

我刚刚搜索了“引用方法和类型”,并找到了一个Connect错误报告“System.InvalidOperationException: The XML element * from namespace * references a references a method and a type”。在这种情况下,有一个操作和一个具有完全相同名称的元素(本地名称和命名空间)。


值得注意的是微软的部分回应:

  

我们不再对ASMX进行增强;我们继续支持其现有功能,但在可能的情况下,我们建议使用WCF。

答案 2 :(得分:1)

我发现了另一个引发错误的案例!这是我的代码:

[WebMethod]
public CheckUpdateResponse CheckUpdate()
{
...
}

好的,让我解释一下:返回类型CheckUpdateResponse是一个结构,CheckUpdate()是方法。因此,在WSDL .NET中在其中一个XML元素中自动添加“Response”后缀到方法名称CheckUpdate ,以描述方法的返回值。 / p>

Etvoilà:它找到了一个重复的元素并给出错误“使用WebMethodAttribute更改方法的消息名称......”

<强>解决方案?我将返回类型重命名为“CheckUpdateResult”,现在一切正常!

我希望这能帮助别人!

答案 3 :(得分:0)

  

所以我只能假设.NET(或者至少是wsdl.exe)不允许你使用Web服务来返回多种方法中相同类型的复杂(用户定义)类型......对吗?

这是不正确的。想象一下,如果它是真的会有多大的痛苦 - 你只能有一个方法返回一个String,一个返回一个Double,一个返回SomeObject,等等......这将是一场噩梦。

我对.NET中的Web服务不是很熟悉,但是从你得到的错误看起来就像是你遇到了XML命名空间的问题 - 也许有一个名称冲突。我尝试按照错误消息中的建议修改WebMethodAttribute

此外,如果由于某些公司隐私/敏感问题而无法发布与您遇到的问题相关的一段代码/文档,您应该发布一个仍然证明您的测试用例的已清理版本。几乎任何“敏感”的东西都应该能够被简化为一个更简单的代码片段,这些代码片段仍然能够突破你的观点而不会背叛任何敏感性。

答案 4 :(得分:0)

很奇怪。通常,WSDL将提供一个公共类型,并且当通过wsdl.exe或svcutil.exe进行编译时,您将获得一个共享的公共类型,以便在同一个接口中的任意数量的方法中使用。

在同一个应用程序中引用多个独立 WSDL时出现问题,这些WSDL共享表面上相同的类型,这导致生成两种不同的CLR类型。有很多方法可以解决这个问题 - 它是众所周知的。然后是将现有业务对象映射到从WSDL生成的类型的一些相关问题。另一个先前探索的景观。

但你说的是不同的东西。

答案 5 :(得分:0)

使用WSDL.exe有一个开关/共享类型。这应该解决这个问题。

此外,我不同意它是Microsoft的东西,因为相同的类被暴露为多个wsdl中的不同复杂类型。这不是一个很好的抽象设计。

准备参考用于共享类型的Microsoft文档 打开类型共享功能。此功能为不同服务之间共享的相同类型创建一个具有单一类型定义的代码文件(名称空间,名称和电线签名必须相同)。使用http:// URL作为命令行参数引用服务,或者为本地文件创建discomap文档。