Returning a custom class.....

Discussion in 'ASP .Net Web Services' started by Manni, Nov 13, 2003.

  1. Manni

    Manni Guest

    Hi!

    I have a component (MyComp) with a class TheElement.

    I write a Webservice (MyService) with tow methods - one returning a DataSet,
    the other returning TheElement.

    Next I write a client (WinApp) and add a web reference to MyService.

    The two methodes are there, one return (as expected) a class
    System.Data.DataSet.
    BUT the other returns MyService.TheElement instead of MyComp.TheElement.

    The public elements are there and so on, but it is a different class!!!

    I tried a lot of things
    1.) DataSet is derivied from MarshalByRefObject
    When I add this to my class, it does not work --
    Marsh....implements an interface -- as error from the service.
    2.) DataSet implement ISerializeable
    I can't implement this since the class should also work with
    Windows.CE - no ISerializeable there!!!
    3.) I write a method in my class (TheElement) wich takes
    MyService.TheElement...
    This does not work since this class is generated by the Proxy
    and therefore not available on the server.

    Even if there could be a way with conditionals or so - my intention is to
    get a proxy from the WebService - automaticly!!
    Of course I can change the Proxy - but the WebService is complex and under
    development - it will grow.
    So I would always (at a change of the WebService) have to "recode" the
    proxy, instead of simply say "refresh".

    It is possible (since it works with DataSet), but how can it be done???

    Thanks a lot

    Manfred
     
    Manni, Nov 13, 2003
    #1
    1. Advertising

  2. Manni

    MSFT Guest

    Hi Manfred,

    I think you have to implement the ISerializable Interface in your custom
    class (DataSet also implements this interface). When pass a object from web
    service, it first will be Serialized by calling GetObjectData method in
    ISerializable Interface. If you can't implement the ISerializable
    Interface, you may consider converting your object to a dataset first and
    then pass it from web service. For example, save its all property to a
    datatable and recreate this object based on values in this datatable.

    Luke
    Microsoft Online Support

    Get Secure! www.microsoft.com/security
    (This posting is provided "AS IS", with no warranties, and confers no
    rights.)
     
    MSFT, Nov 14, 2003
    #2
    1. Advertising

  3. Manni

    Manni Guest

    Thanks for your fast response Luke!

    As I mentioned - I use this things in mobile Apps - so the "inbetween" of
    using a dataset is
    not wanted.
    To do things like this - I could write some methods converting
    "ServiceNS.MyType" to CompoNS.MyType.

    But that is not what I asked!!!

    Another MS guy gave me a hint to

    > http://support.microsoft.com/default.aspx?scid=kb;en-us;326790


    With the XMLNamespace for the Component classes - now I got it work!
    This means, that the Components class is serialized with the right NS,
    so that the conversion from MySvc.Class to MyCompo.Class works.

    I only to edit the Proxy (using my Components namespace and delete the
    returnclass defined),
    but it works now.

    So I have a much better solution than my first one.

    BUT still there is no explanation how how the Framework does the thing with
    DS.
    There the proxy is automaticly defined right!!!!

    Since my project uses about 30 Classes within that WebService - it's a
    little hard to edit the proxy
    all the times (it changes frequently because of development on the
    webservice).

    But it works!

    I repeat:
    MS can do the "automatic fitting proxy generation" with DS (and other
    classes)!!!
    What is the mystery behind this???
    Can we ("normal" developers) do this also??
    Or is there a hack in WSDL that it "knows" the framework classes???

    Manfred
     
    Manni, Nov 14, 2003
    #3
  4. Manni

    Scott Mason Guest

    Hello.
    In response to your questions regarding the automatic (on the fly)
    generation of the proxy for the DataSet.
    The DataSet does not actually change any proxy settings anywhere. If you
    have a DS object getting passed back as a return value on a method call,
    the client will expect a DataSet object until you go in and manually change
    it.
    I think that you're refering to the fact that a DataSet object can
    obviously return different data in the form of DataTables, Rows, etc. Each
    DataSet can be completely different and yet all the client has to do is
    expect a single DataSet and it works. Is this what you're talking about?
    If so, then let's talk a bit about the inner workings of a DataSet. The DS
    implements the ISerializable interface and will basically turn all of the
    data it carries into XML format to pass back to the client.
    A DataSet object containing the authors table in the pubs database would
    look something like the soap response below. You would have to implement
    the ISerializable interface if you want something like that.

    <?xml version="1.0" encoding="utf-8" ?>
    - <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    - <soap:Body>
    - <GimmeDataResponse xmlns="http://tempuri.org/">
    - <GimmeDataResult>
    - <xs:schema id="ScottsDataSet" xmlns=""
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    - <xs:element name="ScottsDataSet" msdata:IsDataSet="true">
    - <xs:complexType>
    - <xs:choice maxOccurs="unbounded">
    - <xs:element name="authors">
    - <xs:complexType>
    - <xs:sequence>
    + <xs:element name="au_id">
    - <xs:simpleType>
    - <xs:restriction base="xs:string">
    <xs:maxLength value="11" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    - <xs:element name="au_lname">
    - <xs:simpleType>
    - <xs:restriction base="xs:string">
    <xs:maxLength value="40" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    - <xs:element name="au_fname">
    - <xs:simpleType>
    - <xs:restriction base="xs:string">
    <xs:maxLength value="20" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    - <xs:element name="phone">
    - <xs:simpleType>
    - <xs:restriction base="xs:string">
    <xs:maxLength value="12" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    - <xs:element name="address" minOccurs="0">
    - <xs:simpleType>
    - <xs:restriction base="xs:string">
    <xs:maxLength value="40" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    - <xs:element name="city" minOccurs="0">
    - <xs:simpleType>
    - <xs:restriction base="xs:string">
    <xs:maxLength value="20" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    - <xs:element name="state" minOccurs="0">
    - <xs:simpleType>
    - <xs:restriction base="xs:string">
    <xs:maxLength value="2" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    - <xs:element name="zip" minOccurs="0">
    - <xs:simpleType>
    - <xs:restriction base="xs:string">
    <xs:maxLength value="5" />
    </xs:restriction>
    </xs:simpleType>
    </xs:element>
    <xs:element name="contract" type="xs:boolean" />
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:choice>
    </xs:complexType>
    - <xs:unique name="Constraint1" msdata:primaryKey="true">
    <xs:selector xpath=".//authors" />
    <xs:field xpath="au_id" />
    </xs:unique>
    </xs:element>
    </xs:schema>
    - <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
    xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    - <ScottsDataSet xmlns="">
    - <authors diffgr:id="authors1" msdata:rowOrder="0">
    <au_id>172-32-1176</au_id>
    <au_lname>Black</au_lname>
    <au_fname>Johnson</au_fname>
    <phone>408 496-7223</phone>
    <address>10932 Bigge Rd.</address>
    <city>Menlo Park</city>
    <state>CA</state>
    <zip>94025</zip>
    <contract>true</contract>
    </authors>
    - <authors diffgr:id="authors2" msdata:rowOrder="1">
    <au_id>213-46-8915</au_id>
    <au_lname>Green</au_lname>
    <au_fname>Marjorie</au_fname>
    <phone>415 986-7020</phone>
    <address>309 63rd St. #411</address>
    <city>Oakland</city>
    <state>CA</state>
    <zip>94618</zip>
    <contract>true</contract>
    </authors>

    etc.


    Thank you,
    Scott Mason
    Microsoft

    This posting is provided "AS IS", with no warranties, and confers no rights.
     
    Scott Mason, Nov 20, 2003
    #4
  5. Manni

    Manni Guest

    There are 2 Problems with your solutuion!
    I can't implement ISerializable since the thing shuold work on the CF,
    where serialization is not available!

    Secound it is not what I want!

    All what I want are 2 things (and it is done wiht classes like DataSet and
    ArrayList).

    I want that the proxy-generatro includes my Namespace as it does with
    System.Data.
    Second I want that the proxy-generator does NOT build it's own class XXXX.

    So another MS Guy form MS (Dino Chiesa) told me:
    The DataSet is special. It works because the Web Service infrastructure
    in
    the .NET Framework looks for a special flag in the runtime-provided XML
    Schema definition called IsDataSet. I believe if wsdl.exe finds this,
    it
    generates a dataset in the proxy.

    So from that point of view - I had to find another solution!
    I found it, by writing a macro for VS.
    This enters the namespace - and then removes the class definitions!
    After a "refresh" on the WS I call this macro - and the rest works fine!

    My one and only question was - if there is a way to let the proxy-gernator
    know
    He, this class is a "Shared assembly class" (like DataSet) - so please
    include the Namespace
    and don't declare this class.

    But since this seems to be done "internal" I have to live with the macro -
    not very hard to do so :)

    Thanks

    Manfred

    "Scott Mason" <> schrieb im Newsbeitrag
    news:...
    > Hello.
    > In response to your questions regarding the automatic (on the fly)
    > generation of the proxy for the DataSet.
    > The DataSet does not actually change any proxy settings anywhere. If you
    > have a DS object getting passed back as a return value on a method call,
    > the client will expect a DataSet object until you go in and manually

    change
    > it.
    > I think that you're refering to the fact that a DataSet object can
    > obviously return different data in the form of DataTables, Rows, etc.

    Each
    > DataSet can be completely different and yet all the client has to do is
    > expect a single DataSet and it works. Is this what you're talking about?
    > If so, then let's talk a bit about the inner workings of a DataSet. The

    DS
    > implements the ISerializable interface and will basically turn all of the
    > data it carries into XML format to pass back to the client.
    > A DataSet object containing the authors table in the pubs database would
    > look something like the soap response below. You would have to implement
    > the ISerializable interface if you want something like that.
    >
    > <?xml version="1.0" encoding="utf-8" ?>
    > - <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    > xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    > - <soap:Body>
    > - <GimmeDataResponse xmlns="http://tempuri.org/">
    > - <GimmeDataResult>
    > - <xs:schema id="ScottsDataSet" xmlns=""
    > xmlns:xs="http://www.w3.org/2001/XMLSchema"
    > xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    > - <xs:element name="ScottsDataSet" msdata:IsDataSet="true">
    > - <xs:complexType>
    > - <xs:choice maxOccurs="unbounded">
    > - <xs:element name="authors">
    > - <xs:complexType>
    > - <xs:sequence>
    > + <xs:element name="au_id">
    > - <xs:simpleType>
    > - <xs:restriction base="xs:string">
    > <xs:maxLength value="11" />
    > </xs:restriction>
    > </xs:simpleType>
    > </xs:element>
    > - <xs:element name="au_lname">
    > - <xs:simpleType>
    > - <xs:restriction base="xs:string">
    > <xs:maxLength value="40" />
    > </xs:restriction>
    > </xs:simpleType>
    > </xs:element>
    > - <xs:element name="au_fname">
    > - <xs:simpleType>
    > - <xs:restriction base="xs:string">
    > <xs:maxLength value="20" />
    > </xs:restriction>
    > </xs:simpleType>
    > </xs:element>
    > - <xs:element name="phone">
    > - <xs:simpleType>
    > - <xs:restriction base="xs:string">
    > <xs:maxLength value="12" />
    > </xs:restriction>
    > </xs:simpleType>
    > </xs:element>
    > - <xs:element name="address" minOccurs="0">
    > - <xs:simpleType>
    > - <xs:restriction base="xs:string">
    > <xs:maxLength value="40" />
    > </xs:restriction>
    > </xs:simpleType>
    > </xs:element>
    > - <xs:element name="city" minOccurs="0">
    > - <xs:simpleType>
    > - <xs:restriction base="xs:string">
    > <xs:maxLength value="20" />
    > </xs:restriction>
    > </xs:simpleType>
    > </xs:element>
    > - <xs:element name="state" minOccurs="0">
    > - <xs:simpleType>
    > - <xs:restriction base="xs:string">
    > <xs:maxLength value="2" />
    > </xs:restriction>
    > </xs:simpleType>
    > </xs:element>
    > - <xs:element name="zip" minOccurs="0">
    > - <xs:simpleType>
    > - <xs:restriction base="xs:string">
    > <xs:maxLength value="5" />
    > </xs:restriction>
    > </xs:simpleType>
    > </xs:element>
    > <xs:element name="contract" type="xs:boolean" />
    > </xs:sequence>
    > </xs:complexType>
    > </xs:element>
    > </xs:choice>
    > </xs:complexType>
    > - <xs:unique name="Constraint1" msdata:primaryKey="true">
    > <xs:selector xpath=".//authors" />
    > <xs:field xpath="au_id" />
    > </xs:unique>
    > </xs:element>
    > </xs:schema>
    > - <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
    > xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    > - <ScottsDataSet xmlns="">
    > - <authors diffgr:id="authors1" msdata:rowOrder="0">
    > <au_id>172-32-1176</au_id>
    > <au_lname>Black</au_lname>
    > <au_fname>Johnson</au_fname>
    > <phone>408 496-7223</phone>
    > <address>10932 Bigge Rd.</address>
    > <city>Menlo Park</city>
    > <state>CA</state>
    > <zip>94025</zip>
    > <contract>true</contract>
    > </authors>
    > - <authors diffgr:id="authors2" msdata:rowOrder="1">
    > <au_id>213-46-8915</au_id>
    > <au_lname>Green</au_lname>
    > <au_fname>Marjorie</au_fname>
    > <phone>415 986-7020</phone>
    > <address>309 63rd St. #411</address>
    > <city>Oakland</city>
    > <state>CA</state>
    > <zip>94618</zip>
    > <contract>true</contract>
    > </authors>
    >
    > etc.
    >
    >
    > Thank you,
    > Scott Mason
    > Microsoft
    >
    > This posting is provided "AS IS", with no warranties, and confers no

    rights.
    >
    >
     
    Manni, Nov 21, 2003
    #5
  6. I did some research on this problem

    By deafult Web service proxy will include all public classes ,This is
    generated by .NET frame work,We can't change this behaviour

    If you don't want to change this behaviour,Make sure Web service return
    type to Native type objects (Example :native type can be Dataset or object
    type)

    Following document explains about native types
    XML Web service Type Marshaling
    http://samples.gotdotnet.com/quickstart/aspplus/doc/webservicetypes.aspx

    in my example I didn't see any Namespace differences between Dataset and
    Custom class

    If i mis understood this question,Can you please send me your sample
    application and please give me brief description,What kind of results you
    are expecting and What is the current behaviour

    -Thank you
    Madhu
    (Microsoft .NET DS Team)
     
    Madhu Ponduru [MSFT], Nov 27, 2003
    #6
  7. Manni

    Manni Guest

    Hy Madhu!

    Thanks for your information!

    The senteces
    > By deafult Web service proxy will include all public classes ,This is
    > generated by .NET frame work,We can't change this behaviour

    would explain all. But there is an "except" to this senteces!
    ....will include all public classes, except classes like DataSet,
    ArrayList.....

    It would be good (for my solution) to have a way to tell the FW not to
    generate
    proxy classes for my custom classes it I don't like it! Some behaviour like
    "if class exists in the referneces don't build a proxy class".

    You write
    > in my example I didn't see any Namespace differences between Dataset and
    > Custom class


    There is a difference - for DataSet no proxy class will be gernated. For
    ArrayList it is the same.
    For your custom class there will be a proxy class generated so that means
    you have:
    System.Data.DataSet
    and
    ApplicationNS.ServiceNS.CustomClass.

    A small example:
    You have a WS with two methods - MethodReturnDataSet and
    MethodReturnMyClass.
    You generate a proxy and get:
    namespace ApplicationNS.WhatIvChosen {
    using ......
    using System.Data; /!!!!!!!!!

    class TheSvcName {

    [XML.....]
    public DataSet MethodReturnDataSet() {
    ........

    [XML.....]
    public MyClass MethodReturnMyClass {
    .......

    } //end of TheSvcName class

    class MyClass {
    public.....
    //all the public members (attributes)
    } //end of MyClass

    } // end of NS

    As you see, there is a difference - for DataSet there is no proxy class
    generated.
    Instead System.Data is included with using.

    What I would like to have is the following code:
    namespace ApplicationNS.WhatIvChosen {
    using ......
    using System.Data; /!!!!!!!!!
    using MyAssembly; //assume my class is from that assembly!

    class TheSvcName {

    [XML.....]
    public DataSet MethodReturnDataSet() {
    ........

    [XML.....]
    public MyClass MethodReturnMyClass {
    .......

    } //end of TheSvcName class

    //NO PROXY CLASS FOR MyClass
    } // end of NS


    Somehow the proxy gernerator must decide when to generate a proxy class and
    when not.
    And that is the behavior wich would be great if it is "changeable".
    I think about something like a checkbox in the discovering wizard like "dont
    generate proxy for referneced classes".
    This apporoach is an easy thing I think - since it is done with DataSet and
    such classes!

    You are right - I could use object instead of my class - but then I would
    loose typechecking at compile time.
    I would have to writ code like
    MyClass Var=(MyClass) TheSvc.MethodReturnMyClass();
    And that kind of upcast is not checkable for the compiler. So an exception
    would occur at runtime.

    I hope you can understand better what my questions are about!

    For the moment I have a macro in VS.NET wich changes the proxy file.
    It is easy since the proxy classes follow the serviceclass and the using
    statements are right
    befor the service class begins.

    So search for the first class in the file. Search back for a ; (ending the
    last using statement).
    Go down one line - enter "using MyNamespace;"
    Search forward for class (now again at the serviceclass), search forward for
    the next class.
    So I find the first proxy class.
    Search back for the closing bracket }.
    Go down one line and replace the whole code to the rest of the file with a
    closing bracket (for the namespace).

    This macro approach works fine if my service only returns classes for wich I
    have a reference at the client.

    Manfred
     
    Manni, Nov 27, 2003
    #7
  8. Hi Manfred,

    Thanks for giving such a valuable information

    Your feedback is very important to us,You can always submit your feedback
    online from this link

    http://register.microsoft.com/mswish/suggestion.asp

    I will send your feedback to Microosft VIsual studio.NET tools team,They
    may consider this request in netx release of VS.NET

    -Thank you
    Madhu
     
    Madhu Ponduru [MSFT], Dec 1, 2003
    #8
    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. E11
    Replies:
    1
    Views:
    4,953
    Thomas Weidenfeller
    Oct 12, 2005
  2. Replies:
    11
    Views:
    699
    Christos Georgiou
    May 2, 2006
  3. c4tech
    Replies:
    0
    Views:
    400
    c4tech
    Jul 1, 2009
  4. Iain

    Returning a custom class in a Web Service

    Iain, Jul 3, 2004, in forum: ASP .Net Web Services
    Replies:
    2
    Views:
    140
  5. suresh_C#

    returning custom class from web service

    suresh_C#, Sep 21, 2004, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    119
    suresh_C#
    Sep 21, 2004
Loading...

Share This Page