complex types in a Web service

Discussion in 'ASP .Net Web Services' started by William F. Kinsley, Feb 13, 2006.

  1. I'm trying to use complex types in a Web service as follows:

    // In Some Util Library
    [Serializable]
    public class PatientFilter
    {
    ....
    }

    [Serializable]
    public class PatientCollection : IEnumerable
    {
    ....
    }

    // In the webservice asmx.cs
    [WebMethod]
    public PatientCollection GetPatients(PatientFilter filter)
    {
    ....
    }


    So this all works great, except that on the client side, after adding a web
    reference, two things happen that aren't so good.

    The first is that another PatientFilter class is auto generated in the
    Reverence.cs in the WebReference namespace. This causes type problems
    between the original PatientFilter class and the one in the Reference.cs. A
    solution to this is to delete the auto generated class in Reference.cs and
    everything works, but this is annoying as the class is constantly being
    regenerated and I'm pretty sure there's a better way. When using a DataSet
    class as a parameter, the auto generating tool does not make a new class in
    Reference.cs. As best I can guess this is because the WSDL defines the
    DataSet parameter as:

    <s:complexType>
    <s:sequence>
    <s:element ref="s:schema" />
    <s:any />
    </s:sequence>
    </s:complexType>


    So my 1st question is how do I get my class to do the same, or similar thing
    so that a new class does not get auto generated in Reference.cs


    The second thing that happens that is annoying is that the GetPatients()
    returns an object[] instead of a PatientCollection in the WebReference
    class. Again, editing the Reference.cs and replacing the object[] return
    parameter with PatientCollection fixes the problem and everything works.
    The WSDL for this return value ends up being:
    <s:complexType>
    <s:sequence>
    <s:element minOccurs="0" maxOccurs="1" name="GetPatientsResult"
    type="tns:ArrayOfAnyType" />
    </s:sequence>
    </s:complexType>

    So my second question is how do I get the method to return a
    PatientCollection instead of an ArrayOfAnyType automatically in the auto
    generated class.
    William F. Kinsley, Feb 13, 2006
    #1
    1. Advertising

  2. Hi William,

    Welcome to the MSDN newsgroup.

    As for the two question you mentioned, here are some of my understanding
    and suggestion:

    1.So my 1st question is how do I get my class to do the same, or similar
    thing
    so that a new class does not get auto generated in Reference.cs
    ===============================
    This is a bit hard since the client webservice proxy generate the types
    according to the webservice's WSDL document. And WSDL document use XML
    schema's standard types to represent different object types used in
    webservice methods, this is for interop consideration since the webservice
    will be consumed by different client platform (c++, java, php.....). And
    for list/collection like type, WSDL will always use SOAP Array to represent
    it, thus the .NET client proxy will generate the Array for such
    objects(parameter or return type). If you do need to use .NET specific
    type, you need to manually change the client genernated proxy code.


    2.So my second question is how do I get the method to return a
    PatientCollection instead of an ArrayOfAnyType automatically in the auto
    generated class.
    ===============================
    I think this is likely caused by the custom collection class you used only
    implement IEnumerable interface which is not sufficient to let the ASP.NET
    webservice engine automatically use SOAP Array to represent it in WSDL. I
    think you can consider the following means:

    1) Instead of only implment IEnumerable, you can consider make the
    colleciton class derived from CollectionBase class and implements those
    methods. Such collectionbase derived class will be represend by SOAP
    Array(of certain custom class type) automatically in WSDL document.


    2) You can also try explicitly apply the following attribute in your
    webmethod to indicate that the return type of the webmethod is an Array
    (and the Array item's type). For example:

    [WebMethod]
    [return:XmlArray()]
    [return:XmlArrayItem(typeof(User))]
    public UserCollection GetWebUsers(int count)
    {
    ...............
    }


    Hope this helps.

    Regards,

    Steven Cheng
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
    Steven Cheng[MSFT], Feb 14, 2006
    #2
    1. Advertising

  3. Hi Steven,

    I understand that the WSDL specifies the complex types for interop purposes,
    however it does not do this for the DataSet type, yet the Reference.cs file
    still manages to type it to a DataSet. So my question #1 is really how do I
    do what the DataSet (and some other .net types) are doing?

    As for question #2, having it return an array of Patients types isn't what
    I'm looking for, I want the return type in the Reference.cs to actually be
    my original type (without of course another proxy class from question #1,
    but that's a separate issue). So is there an attribute that will change the
    return type to be my class in the WSDL?

    Thanks





    "Steven Cheng[MSFT]" <> wrote in message
    news:eek:...
    > Hi William,
    >
    > Welcome to the MSDN newsgroup.
    >
    > As for the two question you mentioned, here are some of my understanding
    > and suggestion:
    >
    > 1.So my 1st question is how do I get my class to do the same, or similar
    > thing
    > so that a new class does not get auto generated in Reference.cs
    > ===============================
    > This is a bit hard since the client webservice proxy generate the types
    > according to the webservice's WSDL document. And WSDL document use XML
    > schema's standard types to represent different object types used in
    > webservice methods, this is for interop consideration since the webservice
    > will be consumed by different client platform (c++, java, php.....). And
    > for list/collection like type, WSDL will always use SOAP Array to
    > represent
    > it, thus the .NET client proxy will generate the Array for such
    > objects(parameter or return type). If you do need to use .NET specific
    > type, you need to manually change the client genernated proxy code.
    >
    >
    > 2.So my second question is how do I get the method to return a
    > PatientCollection instead of an ArrayOfAnyType automatically in the auto
    > generated class.
    > ===============================
    > I think this is likely caused by the custom collection class you used only
    > implement IEnumerable interface which is not sufficient to let the ASP.NET
    > webservice engine automatically use SOAP Array to represent it in WSDL.
    > I
    > think you can consider the following means:
    >
    > 1) Instead of only implment IEnumerable, you can consider make the
    > colleciton class derived from CollectionBase class and implements those
    > methods. Such collectionbase derived class will be represend by SOAP
    > Array(of certain custom class type) automatically in WSDL document.
    >
    >
    > 2) You can also try explicitly apply the following attribute in your
    > webmethod to indicate that the return type of the webmethod is an Array
    > (and the Array item's type). For example:
    >
    > [WebMethod]
    > [return:XmlArray()]
    > [return:XmlArrayItem(typeof(User))]
    > public UserCollection GetWebUsers(int count)
    > {
    > ...............
    > }
    >
    >
    > Hope this helps.
    >
    > Regards,
    >
    > Steven Cheng
    > Microsoft Online Support
    >
    > Get Secure! www.microsoft.com/security
    > (This posting is provided "AS IS", with no warranties, and confers no
    > rights.)
    >
    William F. Kinsley, Feb 14, 2006
    #3
  4. Thanks for your response William,

    So the further question you mentioned all aims at make the autogenerated
    client proxy use our custom class type(.NET specific). I'm afraid this is
    not available through the buildin webservice client proxy genenration
    tool(wsdl.exe). The DataSet class you mentioned is a particular class(which
    is somewhat hardcoded in the wsdl.exe tool's generation logic since there
    is not particular attributes in description for DataSet as we can see).
    I've tried DataTable class also which can not be recognized.
    I think for your scenario, it is more likely that you're going to build a
    custom webservice client proxy generation tool rather than extend the
    current one. Anyway, currently the simplest means is to modify the
    autogenerated proxy class code.

    Regards,

    Steven Cheng
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
    Steven Cheng[MSFT], Feb 15, 2006
    #4
  5. Have you tried controlling the XML serialization for your classes using
    the attributes under the System.Xml.Serialization namespace? I've
    written web services that return lists and are represented as arrays on
    the client (why? You're actually exchange a contract (collection of
    objects) rather than a type (IEnumerable)).
    Javier G. Lozano, Feb 17, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael
    Replies:
    0
    Views:
    531
    Michael
    Sep 16, 2003
  2. Soren Kuula
    Replies:
    2
    Views:
    541
    Henry S. Thompson
    Dec 1, 2005
  3. Spam Catcher
    Replies:
    4
    Views:
    458
    John Saunders [MVP]
    Jul 6, 2007
  4. J.Marsch

    Web Service with complex paramters and return types

    J.Marsch, Nov 14, 2003, in forum: ASP .Net Web Services
    Replies:
    1
    Views:
    117
  5. Mike Dearman
    Replies:
    1
    Views:
    180
    Mike Dearman
    Jun 23, 2004
Loading...

Share This Page