Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the easiest way to save an object to a file without serialization attributes?

I have different kinds of objects in c# that I would like to save to a file (XML is preferred) but I can't use serialization since the class are not written by me but are from a DLL.

What is the best solution for this ?

like image 481
Erez Avatar asked Oct 05 '22 04:10

Erez


2 Answers

I eventually used JavaScriptSerializer and it does exactly what I was looking for:

List<Person> persons = new List<Person>();
persons.Add(new Person(){Name = "aaa"});
persons.Add(new Person() { Name = "bbb" });

JavaScriptSerializer javaScriptSerializer  = new JavaScriptSerializer();
var strData = javaScriptSerializer.Serialize(persons);

var persons2 = javaScriptSerializer.Deserialize<List<Person>>(strData);
like image 79
Erez Avatar answered Oct 13 '22 10:10

Erez


I've whipped up a quick little extension method that will "serialize" to XML, given a non-serializable object. It's pretty rough and doesn't do a heck of a lot of checking and the XML it generates you can easily tweak to meet your needs:

public static string SerializeObject<T>(this T source, bool serializeNonPublic = false)
{
    if (source == null)
    {
        return null;
    }

    var bindingFlags = BindingFlags.Instance | BindingFlags.Public;

    if (serializeNonPublic)
    {
        bindingFlags |= BindingFlags.NonPublic;
    }

    var properties = typeof(T).GetProperties(bindingFlags).Where(property => property.CanRead).ToList();
    var sb = new StringBuilder();

    using (var writer = XmlWriter.Create(sb))
    {
        writer.WriteStartElement(typeof(T).Name);
        if (properties.Any())
        {
            foreach (var property in properties)
            {
                var value = property.GetValue(source, null);

                writer.WriteStartElement(property.Name);
                writer.WriteAttributeString("Type", property.PropertyType.Name);
                writer.WriteAttributeString("Value", value.ToString());
                writer.WriteEndElement();
            }
        }
        else if (typeof(T).IsValueType)
        {
            writer.WriteValue(source.ToString());
        }

        writer.WriteEndElement();
    }

    return sb.ToString();
}

I tested it on this class:

private sealed class Test
{
    private readonly string name;

    private readonly int age;

    public Test(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public string Name
    {
        get
        {
            return this.name;
        }
    }

    public int Age
    {
        get
        {
            return this.age;
        }
    }
}

as well as the number 3 and object. The resulting XML is as such:

<?xml version="1.0" encoding="utf-16"?>
<Test>
  <Name Type="String" Value="John Doe" />
  <Age Type="Int32" Value="35" />
</Test>

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

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

respectively.

like image 42
Jesse C. Slicer Avatar answered Oct 13 '22 10:10

Jesse C. Slicer