VS2005 - Passing Collection/Array as a Parameter to a Web Service

I have a web service that I'm trying to call using VS2005. I'm not understanding how to pass a collection as a parameter into my web service. (This does work in VS2003 by modifying the Reference.vb file, which does not exist in VS2005.)

Here is a simple web service:

<WebMethod()> _
Public Sub TestMethod(ByRef oTestItems As GlobalAccountsClasses.TestItems)

End Sub

Here is the TestItems collection along with the TestItem class:

Public Class TestItems
Inherits CollectionBase

'Retrieves an item from the collection by index
Default Public Property Item(ByVal Index As Integer) As TestItem
Get
Return CType(List.Item(Index), TestItem)
End Get
Set(ByVal Value As TestItem)
List.Item(Index) = Value
End Set
End Property

'Adds an item to the collection
Public Function Add(ByVal Item As TestItem) As Integer
Return List.Add(Item)
End Function

Public Sub Remove(ByVal Item As TestItem)
List.Remove(Item)
End Sub
End Class

Public Class TestItem
Private _FirstName As String
Private _LastName As String

Public Property FirstName() As String
Get
Return _FirstName
End Get
Set(ByVal Value As String)
_FirstName = Value
End Set
End Property

Public Property LastName() As String
Get
Return _LastName
End Get
Set(ByVal Value As String)
_LastName = Value
End Set
End Property
End Class

Here is the VS2005 generated wsdl definition of what we have so far:

<s:element name="TestMethod">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="oTestItems" type="tns:ArrayOfTestItem" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="ArrayOfTestItem">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="TestItem" nillable="true" type="tns:TestItem" />
</s:sequence>
</s:complexType>
<s:complexType name="TestItem">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="FirstName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="LastName" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="TestMethodResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="oTestItems" type="tns:ArrayOfTestItem" />
</s:sequence>
</s:complexType>
</s:element>

Here is what I'm expecting to be able to do in my aspx.vb but I can't:

Dim oTestWebService As New GlobalAccountsWebService_Test.Test
Dim oTestItems As New GlobalAccountsWebService_Test.TestItems
Dim oTestItem As New GlobalAccountsWebService_Test.TestItem
oTestItem.FirstName = "FN"
oTestItem.LastName = "LN"
oTestItems.Add(oTestItem)
oTestWebService.TestMethod(oTestItems)

Any help would be greatly appreciated.



Answer this question

VS2005 - Passing Collection/Array as a Parameter to a Web Service

  • ManjuVijay

    It appears that my VS2003 "ASP.NET Web Application" converted to VS2005 as a "Web Site" project. My installation of VS2005 did not have "ASP.NET Web Application" as a choice when creating a new project so I had to download a patch from the following URL: http://msdn.microsoft.com/asp.net/reference/infrastructure/wap/default.aspx. Once I downloaded this, I now have a Reference.vb file that I can modify and get where I need to be.
  • dophine

    Rodrigo,

    Thanks for the reply. I've looked everywhere for a reference.vb file but I can't find one anywhere in my project. Under each web service I have a .disco, .discomap, and .wsdll; no Reference.vb file anywhere. Where are your Reference.vb files in a VS2005 project

    I'll look into the SchemaImporterExtensions.


  • FireFreak

    Hello Rodrigo,

    You have mentioned in your previous reply something about “SchemaImporterExtensions”, and have said that it can modify the way the proxy class is generated.

    I currently need that ability of modifying the proxy class generation.

    My case is the following:

    1- I am using the same ClassLibrary on the server and client side.

    2- Web Methods are returning objects of types that exist in the ClassLibrary (example: ClassA).

    3- When I “Update Web Reference” in Visual Studio 2005 it creates a Reference.cs file. It implements a new dynamically generated version of ClassA, which only contains private fields and public properties with the same names as the alternate properties in the original ClassA of the ClassLibrary.

    4- Each time their would be changes in the web service, I need to:

    a. “Update Web Reference

    b. Open the Reference.cs file and add a “using” statement to include the ClassLibrary.

    c. And remove all the dynamically generated versions of the original ClassLibrary.ClassA class.

    d. And modify the types that are generated in the return values of the web methods (in case I was using a CollectionBase derived class), example: ClassA[] to ClassACollection class.

    If the use of “SchemaImporterExtensions” helps me avoid this annoying modification each time I need to update the web reference, please reply with whatever deficient information or code examples I should know.

    Thanks in advance,

    Fadi


  • Ultrawhack

    jason,

    Reference.vb is still there and you can modify it as you used to do it with VS2003.

    However modifying it each time you update the web references is quite annoying. For that a new feature is included with .NET Framework 2.0 that is called "SchemaImporterExtensions"

    Schema importer extensions can modify the way the proxy class is generated for example adding "using" statements and avoiding the type convertion the wsdl tool implements.... I found it very useful with generic types for example (List<T> is converted to T[] by wsdl.exe)

    Please let me know whether you need more info. on the SIE implementation.

    Rgds

    Rodrigo


  • Namrata Prashar

    Hello Rodrigo,

    You have mentioned in your previous reply something about “SchemaImporterExtensions”, and have said that it can modify the way the proxy class is generated.

    I currently need that ability of modifying the proxy class generation.

    My case is the following:

    1- I am using the same ClassLibrary on the server and client side.

    2- Web Methods are returning objects of types that exist in the ClassLibrary (example: ClassA).

    3- When I “Update Web Reference” in Visual Studio 2005 it creates a Reference.cs file. It implements a new dynamically generated version of ClassA, which only contains private fields and public properties with the same names as the alternate properties in the original ClassA of the ClassLibrary.

    4- Each time their would be changes in the web service, I need to:

    a. “Update Web Reference

    b. Open the Reference.cs file and add a “using” statement to include the ClassLibrary.

    c. And remove all the dynamically generated versions of the original ClassLibrary.ClassA class.

    d. And modify the types that are generated in the return values of the web methods (in case I was using a CollectionBase derived class), example: ClassA[] to ClassACollection class.

    If the use of “SchemaImporterExtensions” helps me avoid this annoying modification each time I need to update the web reference, please reply with whatever deficient information or code examples I should know.

    Thanks in advance,

    Fadi


  • AAKurtz

    You have to select the web reference in your client project. Then click on "Show all files".... you should see Reference.map, Service.disco and Service.wsdl

    Under Reference.map you should have the Reference.vb proxy class.


  • http200

    Hello Rodrigo,

    You have mentioned in your previous reply something about “SchemaImporterExtensions”, and have said that it can modify the way the proxy class is generated.

    I currently need that ability of modifying the proxy class generation.

    My case is the following:

    1- I am using the same ClassLibrary on the server and client side.

    2- Web Methods are returning objects of types that exist in the ClassLibrary (example: ClassA).

    3- When I “Update Web Reference” in Visual Studio 2005 it creates a Reference.cs file. It implements a new dynamically generated version of ClassA, which only contains private fields and public properties with the same names as the alternate properties in the original ClassA of the ClassLibrary.

    4- Each time their would be changes in the web service, I need to:

    a. “Update Web Reference

    b. Open the Reference.cs file and add a “using” statement to include the ClassLibrary.

    c. And remove all the dynamically generated versions of the original ClassLibrary.ClassA class.

    d. And modify the types that are generated in the return values of the web methods (in case I was using a CollectionBase derived class), example: ClassA[] to ClassACollection class.

    If the use of “SchemaImporterExtensions” helps me avoid this annoying modification each time I need to update the web reference, please reply with whatever deficient information or code examples I should know.

    Thanks in advance,

    Fadi


  • Dennis Mark Thorsen

    Hello Rodrigo,

    You have mentioned in your previous reply something about “SchemaImporterExtensions”, and have said that it can modify the way the proxy class is generated.

    I currently need that ability of modifying the proxy class generation.
    My case is the following:
    1- I am using the same ClassLibrary on the server and client side.
    2- Web Methods are returning objects of types that exist in the ClassLibrary (example: ClassA).
    3- When I “Update Web Reference” in Visual Studio 2005 it creates a Reference.cs file. It implements a new dynamically generated version of ClassA, which only contains private fields and public properties with the same names as the alternate properties in the original ClassA of the ClassLibrary.

    4- Each time their would be changes in the web service, I need to:
    a. “Update Web Reference
    b. Open the Reference.cs file and add a “using” statement to include the ClassLibrary.
    c. And remove all the dynamically generated versions of the original ClassLibrary.ClassA class.
    d. And modify the types that are generated in the return values of the web methods (in case I was using a CollectionBase derived class), example: ClassA[] to ClassACollection class.

    If the use of “SchemaImporterExtensions” helps me avoid this annoying modification each time I need to update the web reference, please reply with whatever deficient information or code examples I should know.

    Thanks in advance,
    Fadi


  • Tryst

    Fadi,

    here you have an example of a SIE....

    1. First create a class library for the SIE

    2. Create a new class that inherits from System.Xml.Serialization.Advanced.SchemaImporterExtension

    3. Override the ImportSchemaType method..... here you have an example of that in where I change the proxy generation so you have List<T> in the proxy instead of T[]

    public override string ImportSchemaType(string name, string ns, XmlSchemaObject context, System.Xml.Serialization.XmlSchemas schemas, System.Xml.Serialization.XmlSchemaImporter importer, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, System.Xml.Serialization.CodeGenerationOptions options, System.CodeDom.Compiler.CodeDomProvider codeProvider)

    {

    try

    {

    // use the SIE only for my types

    if (!ns.Contains("mynamespace.com"))

    return null;

    string typeName = name;

    if (!string.IsNullOrEmpty(name))

    {

    // When returning List<T> it is serialized as ArrayOfT .... so I check for that to change it back to List<T>

    if (name.StartsWith("ArrayOf"))

    {

    // Using CodeDOM I add the using statement to System.Collection.Generic in the generated proxy

    mainNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));

    // I get the actual generic type (T)

    string nType = name.Substring(7);

    typeName = string.Format("List<{0}>", nType);

    }

    }

    // I return List<T> instead of ArrayOfT

    return typeName;

    }

    catch

    {

    // returning null will do the usual stuff.

    return null;

    }

    }

    4. Sign the assembly and put it in the GAC

    5. Register the SIE in the machine.config....

    <system.xml.serialization>

    <schemaImporterExtensions>

    <add name="someName" type="full type name here" />

    </schemaImporterExtensions>

    </system.xml.serialization>

    6. Restart Visual Studio to see the changes.

    Hope it helps

    Rgsd

    Rodrigo


  • VS2005 - Passing Collection/Array as a Parameter to a Web Service