views:

423

answers:

3

This example uses a StringWriter to hold the serialized data, then calling ToString() gives the actual string value:

Person john = new Person();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));
StringWriter stringWriter = new StringWriter();
xmlSerializer.Serialize(stringWriter, john);
string serializedXML = stringWriter.ToString();

Is there any easier/Cleaner way to do this? All of the Serialize() overloads seem to use a Stream or Writer.

UPDATE: Asked a similar question about serializing an IEnumerable via an Extension Method .

+1  A: 

I created this helper method, but I haven't tested it yet. Updated the code per orsogufo's comments (twice):

private string ConvertObjectToXml(object objectToSerialize)
{
    XmlSerializer xmlSerializer = new XmlSerializer(objectToSerialize.GetType());
    StringWriter stringWriter = new StringWriter();

    xmlSerializer.Serialize(stringWriter, objectToSerialize);

    return stringWriter.ToString();
}
SkippyFire
What are you using Convert.ChangeType for?
Paolo Tedesco
For some reason I had it in my head that I needed to cast it back to the right type... but I think you're right, there is no need. Code will be updated.
SkippyFire
Infact no, the serializer takes a generic object as parameter (therefore your extra conversion is wasted). Also note that you don't need to pass the type explicitly, you can ask the object which is its type. Unless, of course, you want to serialize an object as an object of a different type (cannot see why you would want that, but you never know).
Paolo Tedesco
Trying to serialize an object as another type probably wouldn't work, unless it was a base class or interface I would assume. Going to update my code to remove the type reference then.
SkippyFire
-1 for not using a "using" block.
John Saunders
+1 to compensate for stupid downvoting.
Paolo Tedesco
+1.. I agree with osrogufo
Matthew Whited
+3  A: 

Fun with extension methods...

var ret = john.ToXmlString()


public static class XmlTools
{
    public static string ToXmlString<T>(this T input)
    {
        using (var writer = new StringWriter())
        {
            input.ToXml(writer);
            return writer.ToString();
        }
    }
    public static void ToXml<T>(this T objectToSerialize, Stream stream)
    {
        new XmlSerializer(typeof(T)).Serialize(stream, objectToSerialize);
    }

    public static void ToXml<T>(this T objectToSerialize, StringWriter writer)
    {
        new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
    }
}
Matthew Whited
beaten... by... 9... seconds... aaarrrggghhh!
Paolo Tedesco
Ah yes! Totally forgot about that!
SkippyFire
yay... I am normally the late poster for making sure my code works before I submit it.
Matthew Whited
me too, but it's an attitude that doesn't pay off :)
Paolo Tedesco
Is this really an appropriate use of extension methods? I personally believe it is not, but such an opinion wouldn't warrant a vote down so I didn't (just so you don't think so if someone else did).
280Z28
Extension methods allow for easier to read code. You can do somethings like faking duck/dynamic typing and multiple base classes. If people want to deal with calling factory/converter classes then do it way way. You could always just use this as "string ret = XmlTools.ToXmlString(john)" but that just doesn't read as nice.
Matthew Whited
Using a generic method, in this case, wouldn't give a problem in case you serialize an object through a base reference?
Paolo Tedesco
you could provide the generic paramater if you wanted to serialize as a baseclass. But you will most probably lose information if you do that.
Matthew Whited
My point was that in this case it woulb be better to rely on the GetType method...
Paolo Tedesco
Why do you say that? You don't need to provide the type to the generic and it will automatically be the type of the object provided. Only if you explicitly provided a generic parameter would you have to worry.
Matthew Whited
+1  A: 

More or less your same solution, just using an extension method:

static class XmlExtensions {

    // serialize an object to an XML string
    public static string ToXml(this object obj) {
        // remove the default namespaces
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add(string.Empty, string.Empty);
        // serialize to string
        XmlSerializer xs = new XmlSerializer(obj.GetType());
        StringWriter sw = new StringWriter();
        xs.Serialize(sw, obj, ns);
        return sw.GetStringBuilder().ToString();
    }

}

[XmlType("Element")]
public class Element {
    [XmlAttribute("name")]
    public string name;
}

class Program {
    static void Main(string[] args) {
        Element el = new Element();
        el.name = "test";
        Console.WriteLine(el.ToXml());
    }
}
Paolo Tedesco
+1 for a different way of doing things, and a complete example!
SkippyFire
-1 for no "using" block.
John Saunders