locked
How to log objects without xml or binary serialization RRS feed

  • Question

  • Hi,

    we have custom classes and we need them serialized. We have too many custom object types and using xml serialization takes a very long time when we don't know the object type, so we dont use that. What we basicaly need is, to log the object in plain text, this is for logging and auditing purposes. Serialization or later de-serialization is not needed.

    So we used reflection and generated an xml string, which has objects, their properties and theri values. But an object property can also be another custom object even a generic list so recursive part was a real pain .... -Not to mention about lazy initialized properties.-

    I thought maybe System.Xml.Linq can help us, or maybe there is a better way to do this, so any keywords or comments are appreciated. All we need is understandable text for each property that has a value.

    Any suggestions?

     

    Thanks

    Monday, February 7, 2011 6:58 PM

Answers

  • Basically you will need a recursive object serializer that will traverse the object graph. I don't think LINQ for Xml will help here.
    I am not sure why Xml serialization would take so long?

    How about something like this:

    void SerializeObject(object serializableObject, Stream output)
        {
          XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
          XmlTextWriter writer = new XmlTextWriter(output, Encoding.UTF8);
          serializer.Serialize(output, serializableObject);
        }
    
    Tuesday, February 8, 2011 12:56 AM

All replies

  • Basically you will need a recursive object serializer that will traverse the object graph. I don't think LINQ for Xml will help here.
    I am not sure why Xml serialization would take so long?

    How about something like this:

    void SerializeObject(object serializableObject, Stream output)
        {
          XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
          XmlTextWriter writer = new XmlTextWriter(output, Encoding.UTF8);
          serializer.Serialize(output, serializableObject);
        }
    
    Tuesday, February 8, 2011 12:56 AM
  • Hi Greg,

    below our script for xml serialization. Why this takes so long time -around 20 seconds or so!- we do not know. If you have any ideas please let me know. About the problem above i see that there is no magical solution, and our recursive function seems the only suitable solution.

    Thanks for the answer.

     

    GetAllTypes() loads all assemblies from AppDomain.CurrentDomain.GetAssemblies()

    T = GetAllTypes();
    settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.IndentChars = "\t";
    settings.OmitXmlDeclaration = true;
    
    overrides = new XmlAttributeOverrides();
    attrs = new XmlAttributes();
    attrs.Xmlns = false;
    foreach (Type t in T)
    {
    	overrides.Add(t, attrs);
    }
    
    xd = new XmlDocument();
    nav = xd.CreateNavigator();
    
    using (XmlWriter xmlWriter = XmlWriter.Create(nav.AppendChild(), settings))
    {
    	serializer = new XmlSerializer(o.GetType(), overrides, T, new XmlRootAttribute(""), "");
    	namespaces = new XmlSerializerNamespaces();
    	namespaces.Add("", "");
    	serializer.Serialize(xmlWriter, o, namespaces);
    };
    
    foreach (XmlNode xn in xd.ChildNodes)
    	AttributeCleaner(xn);
    

    • Edited by canuzun80 Tuesday, February 8, 2011 12:50 PM CodeFormatted
    Tuesday, February 8, 2011 12:47 PM
  • If you absolutely must pass the type array then I would suggest only creating this once and caching it along with the XmlAttributesOverrides.
    i.e.

      

      static Type[] T = null;
      static XmlAttributeOverrides overrides = null;
    
      void SerializeObject(object serializableObject)
      {
       if (T == null)
       {
        T = GetAllTypes();
        overrides = new XmlAttributeOverrides();
        XmlAttributes attrs = new XmlAttributes();
        attrs.Xmlns = false;
        foreach (Type t in T)
        {
         overrides.Add(t, attrs);
        }
       }
    
       xd = new XmlDocument();
       nav = xd.CreateNavigator();
    
       using (XmlWriter xmlWriter = XmlWriter.Create(nav.AppendChild(), settings))
       {
        serializer = new XmlSerializer(o.GetType(), overrides, T, new XmlRootAttribute(""), "");
        namespaces = new XmlSerializerNamespaces();
        namespaces.Add("", "");
        serializer.Serialize(xmlWriter, o, namespaces);
       };
    
       foreach (XmlNode xn in xd.ChildNodes)
        AttributeCleaner(xn);
      }
    

     

     

     

    Tuesday, February 8, 2011 7:56 PM
  • Will try caching. Thanks again.
    Wednesday, February 9, 2011 2:53 PM