Geeks With Blogs
Shape Without Form He who has a why to live for can bear almost any how

Lets Say ... 

you are working on a COM component in C# that will wrap a Web Service.

Callers of your object \ class want to use a particular web service but can not access it directly. So instead they are going to user your COM object as a proxy.

One of the things your COM object  must do is mirror a class in the Web Service.

There is a method call to GetSomeStuff() that returns a Stuff object.

public Stuff GetSomeStuff(){....

The client consuming your object has no reference to SomeWebService.NamePace.Stuff and so will be unable to use it.

However, they will have a reference to your COM object and so they will be able to get to MyKickButt.ComObject.Stuff

So your stuff must have all the information of the web service stuff.

Got it? Good.

Note: To simplify the XSD command line examples and eliminate path designation I copied my first file into the XSD directory at :

C:\Program Files\Microsoft Visual Studio 8\VC>

Create an XML File (if you don't have one)

First I created an XML file that represents the object in the web service by serializing an instance to XML. 

So I call the Web Service Method and serialize the return value to XML.

I  then wrote the string to a file. The code below can be used to generate a string of XML from the object.

You can write to a file, or to the console and copy and past into a file.

 

public static string SerializeToXmlString(object objectToSerialize, Type type)
        {
            XmlSerializer serializer = new XmlSerializer(type);

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.NewLineHandling = NewLineHandling.Replace;
            settings.NewLineChars = "\n";
            settings.Indent = true;
            settings.Encoding = Encoding.UTF8;

            StringBuilder sb = new StringBuilder();

            XmlWriter writer = XmlWriter.Create(sb, settings);

            try
            {
                serializer.Serialize(writer, objectToSerialize);
            }
            catch (Exception ex)
            {
                throw;

            }
            finally
            {
                writer.Close();
            }

            return sb.ToString();
        }

 

 

Generate the XSD

Once you have the contents in a file you can generate the XSD by using the XML Schema Definition Tool (aka Xsd.exe)

But first, open the file you created and remove the first line that reads:

<?xml version="1.0" encoding="utf-16"?>

XSD does not like this and will generate the error:

Error: There was an error processing 'myClass.xml'.

  - There is no Unicode byte order mark. Cannot switch to Unicode.  

                            

After you remove this save the file (For the sake of the article I call mine MyFile.xml) and run the VS command prompt.

 \Start\Programs\Microsoft Visual Studio\Visual Studio Tools\2005 Visual Studio 2005 Command Prompt

\\type : xsd MyFile.xml

(Note: I copied my file into the 'C:\Program Files\Microsoft Visual Studio 8\VC\ directory to avoid typing ) at the command prompt and an XSD file will be generated in the default location. For more info use XSD /? or see the MSDN article.

 

Generate the Class File

Again from the VS command prompt, use the xsd.exse tool.

xsd.exe /c /l:cs MyFile.Xsd

 

In Code you can serialize as one type and de-serialize as another

In your code you should be able to return the methods return value after you serialize it to XML.

In your code that calls the web service  serialize the return value by sending the object name fully qualified to your Serialization method.

When you de-serialize it, use the type that you created in the step above.

example:

public string GetSomeStuff()
{
    string xmlString; 
    SomeWebService.NamePace.Stuff returnStuff = WService.GetSomeStuff();
    xmlString = SerializeToXmlString(returnVal, typeof(SomeWebService.NamePace.Stuff ));

   // populate your own object if you wish  
   MyKickButt.ComObject.Stuff MyS
tuff =(MyKickButt.ComObject.Stuff) DeserializeFromXmlString XmlString, typeof(MyKickButt.ComObject.Stuff));

   return xmlString;

}

 

The thing I am trying to point out is you serialize it as the remote type, and then de-serialize it as your type.

If your local class doesnt' match the name of the remote you will

have some issues serializing from one to another unless you mark the class with an attribute that will change the element name.

 

To De-serialize you could use code like this.

 

public static object DeserializeFromXmlString(string xmlString, Type objectType)
       {
           XmlTextReader reader = null;
           XmlSerializer serializer;
           Exception localizedException = null;

           object deserializedObject = null;

           try
           {
               reader = new XmlTextReader(new StringReader(xmlString));
               serializer = new XmlSerializer(objectType);
               deserializedObject = (object)serializer.Deserialize(reader);
           }
           catch (Exception ex)
           {
               localizedException = ex;
           }
           finally
           {
               if (reader != null && reader.ReadState != ReadState.Closed)
               {
                   reader.Close();
               }
           }

           if (localizedException != null)
           {
               throw new XmlException(
                   "Could not deserialize parameter string to parameter object",
                   localizedException);
           }

           return deserializedObject;
       }

 

 

Key Words:

xsd.exe

Generate an XSD from XML.

Generate a class from XML.

Generate a class fron WSDL

Posted on Tuesday, March 11, 2008 11:36 AM C# | Back to top


Comments on this post: Auto Generate a class from a Web Service or an XML file.

# re: Auto Generate a class from a Web Service or an XML file.
Requesting Gravatar...
I think using generics for this is a bit more elegant. I converted your example...

public static string SerializeToXmlString<T>(T objectToSerialize)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));

XmlWriterSettings settings = new XmlWriterSettings();
settings.NewLineHandling = NewLineHandling.Replace;
settings.NewLineChars = "\n";
settings.Indent = true;
settings.Encoding = Encoding.UTF8;

StringBuilder sb = new StringBuilder();

XmlWriter writer = XmlWriter.Create(sb, settings);

try
{
serializer.Serialize(writer, objectToSerialize);
}
catch
{
throw;
}
finally
{
writer.Close();
}

return sb.ToString();
}

public static T DeserializeFromXmlString<T>(string xmlString)
{
XmlTextReader reader = null;
XmlSerializer serializer;
Exception localizedException = null;

T deserializedObject = default(T);

try
{
reader = new XmlTextReader(new StringReader(xmlString));
serializer = new XmlSerializer(typeof(T));
deserializedObject = (T)serializer.Deserialize(reader);
}
catch(Exception ex)
{
localizedException = ex;
}
finally
{
if(reader != null && reader.ReadState != ReadState.Closed)
{
reader.Close();
}
}

if(localizedException != null)
{
throw new XmlException("Could not deserialize parameter string to parameter " + typeof(T), localizedException);
}

return deserializedObject;
}
Left by Dave on Jun 17, 2008 2:17 AM

# Thanks for the input, Dave
Requesting Gravatar...
Thanks Dave, that is indeed more elegant. It seems so obvious now, Thanks!
Left by Shape Without Form on Jun 17, 2008 7:22 AM

Your comment:
 (will show your gravatar)


Copyright © [C.B.W] | Powered by: GeeksWithBlogs.net