问题
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.
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.
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 instantiation of the web-service client code:
"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."
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?
回答1:
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:
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.
回答2:
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).
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.
回答3:
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.
Et voilà: it found a duplicate element and give the error "Change the method's message name using WebMethodAttribute..."
Solution? I renamed the return type to "CheckUpdateResult" and now everything works well!
I hope this will help someone!
回答4:
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?
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.
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
.
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.
回答5:
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.
There have been problems when referencing multiple independent WSDL'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.
But you are talking about something different.
回答6:
Use WSDL.exe has a switch /sharetypes. This should take care of the issue.
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.
Ready Reference Microsoft Documentation for sharetypes Turns 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.
来源:https://stackoverflow.com/questions/580042/c-sharp-web-service-client-multiple-web-service-methods-with-same-complex-ret