views:

437

answers:

3

The proxy methods that I am seeing generated for methods that have generics for parameters like List Of <T> are getting converted to arrays in the proxy methods. I am not sure what the problem is, is it that the wsdl.exe that shipped with Visual Studio 2005 can't handle generics, or is it the version of soap on the machine where the web service is deployed or something else? When I view the asmx file in IE 7, I see SOAP 1.1 I expected to see soap 1.2 but that could be an IE7 thing.

+1  A: 

WSDL.EXE and "Add Web Reference" will always use an array. This has nothing to do with generics.

When you upgrade to WCF, you'll be able to specify to use List<T> for lists like this.


XML Schema has neither arrays nor lists, just repeated elements. For instance, if your service returns List<int>, the XML Schema in the WSDL will be something like

<xs:element name="result" maxOccurs="unbounded" type="xs:int"/>

The program that creates the proxy class has to decide whether to translate this into arrays or lists. With "Add Web Reference", the choice is always "array". With "Add Service Reference", you get a number of choices, including List<int>.

John Saunders
I presume that this is only using the DataContractSerializer and not the 'legacy' XmlSerializer?
STW
Of course. "Legacy" implies dead.
John Saunders
STW
@Yooder: it's great that you can live in the past, while the rest of us progress, but note that "legacy" has some practical meaning as well. Example: the "legacy" ASMX web services are in maintenance mode. This greatly reduces the number of bugs that Microsoft will be fixing, down to near zero. Similarly, "Add Web Reference" will never support use of `List<T>` in a proxy.
John Saunders
+1  A: 

.NET's XmlSerializer serialized collections into arrays. I'm unfamiliar if there is any difference for Generic lists but I doubt so. As such SOAP "collections" are always .NET arrays, it's up to the generated proxy to restore the array to the proper collection type (which is really of it's choice).

One other side-effect of collections being serialized into arrays is that only the collection elements are serialized. For example, the below class inherits from a list and adds a new property which will not be serialized by the XmlSerializer, since arrays consist only of elements and not additional properties.

public class MyList : List
{
    public string MyProperty{get;set;}
}

This behaviorism is specific to the XmlSerializer, binary serializers (and perhaps WCF's DataContractSerializer) can handle these conditions.

STW
So if the method contains a Generic List, SOAP converts this to an array in your proxy method, because of that I can't compile with the proxy class if I am using that method, you say it is up to the generated proxy to restore the array to the proper type. Are you saying to manually modify the generated proxy class to pass the correct type? I guess I am still confused without an example.
OutOFTouch
XML Schema has neither arrays nor lists, just repeated elements. The proxy has to decide whether to translate that into arrays or lists. With "Add Web Reference", the choice is always "array". With "Add Service Reference", you get a number of choices.
John Saunders
This project is built in VS 2005, and I don't have the "Add Service Reference" option avalible, but I do appreciate the explanation, So do I have to manually change the auto generated proxy method to use a generic list instead of an array?
OutOFTouch
@OutOfTouch: I would presume that you will need to manually handle the conversion--whether by adding a partial class to the generated proxy (a partial class won't have man-made changes undone during an "update web reference" action) or by mapping the proxy-generated class into a non-generated POCO under your full control.
STW
No. Never edit generated code - your edits will disappear next time you use "Update Web Reference". You can use partial classes to add your own methods to the proxy class. Those methods can call the proxy methods, but load the arrays into the corresponding list type.
John Saunders
I understand now I was having a brain fart, yeah just convert your generic lists back to an array before calling the proxy method.
OutOFTouch
Yoders point about new properties not being serialized is important to remember too. Thanks All who answered.
OutOFTouch
@OutOfTouch: I earned a scar while learning that little tidbit of information :)
STW
A: 

Generics are not interoperable.

Terry Donaghe
many would suggest that 2005/ASMX webservices are not interoperable ;-)
STW
Certainly not, but I don't think they were designed to be, or were they? WCF is designed to try to be as interoperable as possible.
Terry Donaghe
@Yooder: many would be wrong. They're dead, but quite interoperable.
John Saunders
@Terry: the fact that the code returns `List<int>` does not enter into the WSDL. It shows up as `<xs:element type="xs:int" maxOccurs="unbounded"/>`.
John Saunders