Posts tagged ‘c#’

XML Cache

Developers frequently want to get data structures out of their code and into XML. But that bears a performance hit, since every time you read the file you have to parse it. In case of client applications you can avoid it by placing XML objects in the memory. However, in case of web-apps, memory gets destroyed after the request. Besides, you can’t monitor changes in the files themselves. ASP.NET introduced a very useful object called Cache, which is designed to help with precisely that problem. It stores objects on the application level (similar to Application object) but also allows you to monitor changes in the data. The following code is implementation of XmlDocument object storage and file change monitoring:

public static XmlDocument GetDOM(string path, Page page)
{
  if (page.Cache["xmlcache:dom:"+path] != null)
    return (XmlDocument)page.Cache["xmlcache:dom:"+path];
  else
  {
    XmlDocument x = new XmlDocument();
    x.Load(page.MapPath(path));
    page.Cache.Insert("xmlcache:dom:"+path,
      x,new CacheDependency(page.MapPath(path)));
    return x;
  }
}

The methods to store XslTransform and XPathDocument would look exactly the same. However, you should carefully monitor the contents of XslTransform document – CacheDependency object doesn’t monitor internal links of XSLT language, like xsl:import. By the way, I couldn’t find a way to automatically find all those tags in XSLT document and generate CacheDependancy for each of them.

Oh, and one other important thing. ASP.NET 2.0 extended on CacheDependency and introduced an object that monitors changes in SQL database! It’s ideal for many applications where you fill drop-downs with data from database, for example.

Simple Serializer/Deserializer

public static string SerializeObject(object obj)
{
 MemoryStream temp = new MemoryStream();
 XmlSerializer serializer = new XmlSerializer(obj.GetType());
 serializer.Serialize(temp,obj);

 temp.Seek(0,SeekOrigin.Begin);
 byte[] byteArray = new byte[temp.Length];
 int count = 0;
 while (count < temp.Length)
 {
  byteArray[count++] = Convert.ToByte(temp.ReadByte());
 }
 ASCIIEncoding asciiEncoding = new ASCIIEncoding();
 char[] charArray = new char[asciiEncoding.GetCharCount(byteArray, 0, count)];
 asciiEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0);
 return new string(charArray);
}
public static object DeSerializeObject(string s,object obj)
{
 ASCIIEncoding asciiEncoding = new ASCIIEncoding();
 byte[] inp = asciiEncoding.GetBytes(s);
 MemoryStream temp = new MemoryStream();
 XmlSerializer serializer = new XmlSerializer(obj.GetType());

 temp.Write(inp,0, inp.Length);
 temp.Seek(0,SeekOrigin.Begin);
 return serializer.Deserialize(temp);
}

Update: apparently XmlSerializer is pretty limited in which types it can reflect, it’s designed to fit current WDSL schema, which is limited itself. Well, not really, but in any case right now XmlSerializer can’t serialize multidimentional arrays, for example. In the code above you can replace XmlSerializer with SoapFormatter, while keeping everything else exactly the same. That will generate different (SOAP) envelope and you will be able to serialize any type of data.