IXmlSerializable: return type & difference IE / webservice

Discussion in 'ASP .Net Web Services' started by Thomas D., Sep 1, 2005.

  1. Thomas D.

    Thomas D. Guest

    Hello all,

    I'm using the IXmlSerializable interface for a project and encounter some
    problems when testing my webservice in a client application. I know this
    interface is undocumented and not intended for use, but I think this is the
    only solution for my situation. I searched the web, in the hope finding the
    answer, without any luck, so my final hope is with you.

    Let me explain the situation:
    I have an 'export'-wrapper to my regular objects. For each regular object
    there is also an export object. An export object derives from the regular
    object and has for each property in the base object an extra boolean
    property. That extra property tells wether to include the base property in
    the final export (= webservice) or not. That is because not all the
    properties may be exposed all the time (depending on who is requesting it).
    To implement this I have used the IXmlSerializable interface on the export
    objects. Another reason I used the IXmlSerializable interface is that I can
    choose the xml element names, especially for the collections (so I don't get
    ArrayOf.....). The webservice returns export collection objects (implementing
    IXmlSerializable).

    To test my webservice I created a simple WinForms application which calls
    one of the webmethods. But when adding the Web Reference to my test
    application the proxy is not well generated. The return type of the webmethod
    is not my export collection type, but a DataSet. I can work around that issue
    if I let my webmethod only return a 'single' object instead of a collection:
    I just changed the return type in the generated proxy to my custom collection
    type. But then I needed to add an extra reference to my project; that is a
    reference to the assambly which holds the export objects.

    I've tried the same thing to return my custom collection, but that does not
    work unless I do not implement the IXmlSerializable interface on the
    collection. If I do that, I lose the ability to choose a custom xml element
    name. When I implement the IXmlSerializable interface I get this error:
    An unhandled exception of type 'System.InvalidOperationException' occurred
    in system.web.services.dll
    Additional information: Method Export.GetTest can not be reflected.

    I do not understand why this does not work. I get the correct results when I
    open the .asmx page in Internet Explorer, even with the IXmlSerializable
    interface implemented on the collections. If it works in IE, why does it not
    work when generating the proxy? Does someone knows what is going wrong here
    or what I am doing wrong? This problem holds me from going to the next phase
    of the project. Any help is appreciated!

    Below you can find a stripped code example of my situation.


    Thanks in advance and best regards,
    Thomas



    My code:
    ---------------------------
    I have stripped down the code here for simplicity. My export class does not
    derive from any base class, nor does it have the booleans. However when I try
    the code below I still have the same problem.


    // this is the export object which normally derives from 'Test'.
    [Serializable]
    public class TestExport : IXmlSerializable
    {
    private string name;
    private string email;

    public TestExport()
    {
    }

    public string Name
    {
    get { return name; }
    set { name = value; }
    }

    public string Email
    {
    get { return email; }
    set { email = value; }
    }

    #region IXmlSerializable
    public XmlSchema GetSchema()
    {
    return null;
    }

    public void ReadXml(XmlReader reader)
    {
    // Read the opening tag of the encapsulating element
    reader.ReadStartElement();

    // Open the root element for our object
    reader.ReadStartElement("Test");

    reader.ReadStartElement("Name");
    this.Name = reader.ReadString();
    reader.ReadEndElement();

    reader.ReadStartElement("Email");
    this.Email = reader.ReadString();
    reader.ReadEndElement();

    // Close the root element for our object
    reader.ReadEndElement();

    // Read the end tag of the encapsulating element
    reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
    writer.WriteStartElement("Test");
    writer.WriteElementString("Name", this.Name);
    writer.WriteElementString("Email", this.Email);
    writer.WriteEndElement();
    }
    #endregion
    }


    [Serializable]
    public class TestenExport : CollectionBase, IXmlSerializable
    {
    public TestenExport()
    {
    }

    #region IXmlSerializable
    public XmlSchema GetSchema()
    {
    return null;
    }

    public void ReadXml(XmlReader reader)
    {
    // Read the opening tag of the encapsulating element
    reader.ReadStartElement();

    // Open the root element for our object
    reader.ReadStartElement("Tests");

    foreach(TestExport item in this)
    {
    item.ReadXml(reader);
    }

    // Close the root element for our object
    reader.ReadEndElement();

    // Read the end tag of the encapsulating element
    reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
    writer.WriteStartElement("Tests");
    foreach(TestExport item in this)
    {
    item.WriteXml(writer);
    }
    writer.WriteEndElement();
    }
    #endregion

    #region CollectionBase
    public int Add(TestExport @value)
    {
    return List.Add(@value);
    }

    public TestExport this[int index]
    {
    get
    {
    return (TestExport)(List[index]);
    }
    set
    {
    List[index] = value;
    }
    }
    #endregion
    }
     
    Thomas D., Sep 1, 2005
    #1
    1. Advertising

  2. Thomas D.

    Thomas D. Guest

    [SNIP]

    > I've tried the same thing to return my custom collection, but that does not
    > work unless I do not implement the IXmlSerializable interface on the
    > collection. If I do that, I lose the ability to choose a custom xml element
    > name. When I implement the IXmlSerializable interface I get this error:
    > An unhandled exception of type 'System.InvalidOperationException' occurred
    > in system.web.services.dll
    > Additional information: Method Export.GetTest can not be reflected.


    I have found the problem for this. My ReadXml() method in the collection was
    not correct. Here is what I use now:

    public void ReadXml(XmlReader r)
    {
    r.Read(); // move past container
    r.ReadStartElement("Testen");
    while (r.NodeType != XmlNodeType.EndElement)
    {
    r.ReadStartElement("Test");
    string name = r.ReadElementString("Name");
    string email = r.ReadElementString("Email");
    string company = r.ReadElementString("Company");
    r.ReadEndElement();
    this.Add(new TestExport(name, email, company));
    }
    r.ReadEndElement();
    }

    I still need to add a reference to my 'Export objects'-assembly and manually
    change the return types in the proxy. The proxy does not recognize the used
    types itself! This means I will need to manually change the proxy each time
    the webservice changes. Anyone has a solution for this?
     
    Thomas D., Sep 1, 2005
    #2
    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. =?Utf-8?B?Ym9iYnk=?=

    IXmlSerializable

    =?Utf-8?B?Ym9iYnk=?=, Sep 28, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    477
    Teemu Keiski
    Sep 29, 2007
  2. Replies:
    0
    Views:
    313
  3. Frederik Vanderhaegen

    webservice and IXMLSerializable

    Frederik Vanderhaegen, Oct 31, 2006, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    177
    Frederik Vanderhaegen
    Oct 31, 2006
  4. Jeremy
    Replies:
    3
    Views:
    332
    John Saunders [MVP]
    Jul 19, 2007
  5. Jeremy
    Replies:
    1
    Views:
    367
    John Saunders [MVP]
    Jul 18, 2007
Loading...

Share This Page