Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > ASP .Net > ASP .Net Web Services > IXmlSerializable: return type & difference IE / webservice

Reply
Thread Tools

IXmlSerializable: return type & difference IE / webservice

 
 
Thomas D.
Guest
Posts: n/a
 
      09-01-2005
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
}

 
Reply With Quote
 
 
 
 
Thomas D.
Guest
Posts: n/a
 
      09-01-2005
[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?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is my return type for a webservice that uses a database? jm ASP .Net 1 07-08-2008 01:48 AM
what value does lack of return or empty "return;" return Greenhorn C Programming 15 03-06-2005 08:19 PM
difference between return &*i and return i; Ganesh Gella C++ 4 11-12-2004 04:28 PM
WebService return type suggestion Srinivas R. Loka ASP .Net Web Services 1 05-05-2004 03:01 PM
difference between return true; and return false; w i l l Javascript 4 07-04-2003 10:05 PM



Advertisments