Main BLOGGER
Google
WWW THIS BLOG
Saturday, May 06, 2006
 
Interoperability for Document-Based Web Services (ASP.NET)

How to manipulate xsd:anyType in asp.net web service, JWSDP, and gSOAP

This is the first part about ASP.NET

Two good papers are at

http://java.sun.com/developer/technicalArticles/xml/jaxrpcpatterns/index.html

http://java.sun.com/developer/technicalArticles/xml/jaxrpcpatterns2/

Overall, there are five approaches to use document-based web services.

* Using XML in the SOAP Body

* Using a String in the SOAP Body

* Using base64Encoded or raw bytes in the SOAP body

* Using the xsd:any Element in WSDL

* Using the xsd:anyType in WSDL

We will use xsd:anyType for interoperability. And the purpose is to have a state management web service.

It is like a web service based hash table. By the key (xsd:string), client can put/get the value (xsd:anyType) afterwards.

The web service will maintain the stateful information for client. The xml serialization class could be created on the fly.

The assumption is contract first approach, that is, we have a WSDL definition beforehand.

<!-- put state -->

<xsd:element name="putStateRequest">

<xsd:complexType>

<xsd:sequence>

<xsd:element type="xsd:string" name="key" />

<xsd:element type="xsd:anyType" name="value" />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd:element name="putStateResponse">

<xsd:complexType />

</xsd:element>

<!-- get state -->

<xsd:element name="getStateRequest">

<xsd:complexType>

<xsd:sequence>

<xsd:element type="xsd:string" name="key" />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

ASP.net web service

It will use System.Object to map xsd:anyType.

  1. use xmlserializer to do the serialization and deserialization. The only overhead is to declare a normal class.
  2. create a class to implement IXmlSerializable to take over the control of read/write xml. Resource 5 gave a thorough example to control everything by overriding xmlwriter.

The arbitrary class is defined as

public class myObject

{

public int i;

public float f;

public string s;

};

The code example for approach 1 is:

The helper function is from Resources 3.

public static string XmlString(object o)

{

StringWriter writer = null;

try

{

XmlSerializer formatter = new XmlSerializer(o.GetType());

writer = new StringWriter();

formatter.Serialize(writer, o);

return writer.ToString();

}

finally

{

if (writer != null) writer.Close();

}

}

public static object XmlString(string xml, Type type)

{

StringReader reader = null;

try

{

XmlSerializer formatter = new XmlSerializer(type);

reader = new StringReader(xml);

return formatter.Deserialize(reader);

}

finally

{

if (reader != null) reader.Close();

}

}

Testing code

myObject m=new myObject();

m.i = 4;

m.f = 1.3F;

m.s = "hello";

string xmlStr = XmlString(m);

putReq.value = (object)xmlStr;

service.putState(putReq);

getResp = service.getState(getReq);

myObject ret = (myObject)XmlString((string)getResp.getStateResult, m.GetType());

Console.WriteLine(ret.i);

Console.WriteLine(ret.f);

Console.WriteLine(ret.s);

The code example for approach 2 is:

public class myObject2 : IXmlSerializable

{

public int i;

public float f;

public string s;

public XmlSchema GetSchema()

{

return null;

}

public void WriteXml(XmlWriter w)

{

w.WriteStartElement("i");

w.WriteString(i.ToString());

w.WriteEndElement();

w.WriteStartElement("f");

w.WriteString(f.ToString());

w.WriteEndElement();

w.WriteStartElement("s");

w.WriteString(s);

w.WriteEndElement();

}

public void ReadXml(XmlReader r)

{

string str;

r.Read();

r.ReadStartElement("i");

str = r.ReadString();

i = Convert.ToInt32(str);

r.ReadEndElement();

r.ReadStartElement("f");

str = r.ReadString();

f = Convert.ToSingle(str);

r.ReadEndElement();

r.ReadStartElement("s");

s = r.ReadString();

r.ReadEndElement();

}

}

Testing code

myObject2 m2 = new myObject2();

m2.i = 5;

m2.f = 3.4F;

m2.s = "world";

putReq.value = (string)XmlString(m2);

service.putState(putReq);

getResp = service.getState(getReq);

myObject2 ret2 = (myObject2)XmlString((string)getResp.getStateResult, m2.GetType());

Console.WriteLine(ret2.i);

Console.WriteLine(ret2.f);

Console.WriteLine(ret2.s);

Resources

1. Trouble shooting for xmlserializer

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnxmlnet/html/trblshtxsd.asp

2. Tutorial of xmlserializer

http://www.topxml.com/xmlserializer/default.asp

3. serialization/de-serialization helper functions in C#

http://lewismoten.blogspot.com/2005/02/demonstrating-serialization-in-net.html

4. Customize XML Serialization using IXmlSerializable

http://wwww.developerfusion.com/show/4639/

5. .NET XML and SOAP serialization samples

http://www.codeproject.com/soap/Serialization_Samples.asp

http://aspzone.com/blogs/john/articles/167.aspx




<< Home

Powered by Blogger

Google
WWW THIS BLOG