XML Serializable Generic Dictionary

For some reason, the generic Dictionary in .net 2.0 is not XML serializable. The following code snippet is a xml serializable generic dictionary. The dictionary is serializable by implementing the IXmlSerializable interface.

using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue>
    : Dictionary<TKey, TValue>, IXmlSerializable
{
    #region IXmlSerializable Members
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        bool wasEmpty = reader.IsEmptyElement;
        reader.Read();

        if (wasEmpty)
            return;

        while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");

            reader.ReadStartElement("key");
            TKey key = (TKey)keySerializer.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadStartElement("value");
            TValue value = (TValue)valueSerializer.Deserialize(reader);
            reader.ReadEndElement();

            this.Add(key, value);

            reader.ReadEndElement();
            reader.MoveToContent();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        foreach (TKey key in this.Keys)
        {
            writer.WriteStartElement("item");

            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();

            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }
    #endregion
}

Update: Fixed bug Justin pointed out by adding an extra reader.ReadEndElement() and by checking the IsEmptyElement property.


WilsonORMapper CodeSmith Templates

The following CodeSmith templates are to generate the WilsonORMapper mapping file and to generate the business classes that can be mapped to. These templates have the following features…

  • Converts plural table names to single tense class names
  • Cleans table names to make legal class names
  • Column name cleaning
  • Support for all relationships including many to many
  • Template based, easily changed to meet needs
  • Support for Visual Basic and C#
  • Merge support

Update: These templates are now included with CodeSmith.


MSBuild Community Tasks Project releases new version

Announcement

The MSBuild Community Tasks Project releases version v1.1.0.145. There are many new tasks in this release. Special thanks to all the contributors to the project.

Current Community Tasks

TaskDescription
AppPoolControllerAllows control for an application pool on a local or remote machine with IIS installed.
AppPoolCreateCreates a new application pool on a local or remote machine.
AppPoolDeleteDeletes an existing application pool on a local or remote machine.
AssemblyInfoGenerates an AssemblyInfo file using the attributes given.
AttribChanges the attributes of files and/or directories
FileUpdateReplace text in file(s) using a Regular Expression.
FtpUploadUploads a file using File Transfer Protocol (FTP).
FxCopUses FxCop to analyze managed code assemblies and reports on their design best-practice compliance.
MailSends an email message.
Math.AddAdd numbers.
Math.DivideDivide numbers.
Math.MultipleMultiple numbers.
Math.SubtractSubtract numbers.
MoveMoves files on the filesystem to a new location.
NDocRuns NDoc to create documentation.
NUnitRuns tests using the NUnit.
RegistryReadReads a value from the Registry.
RegistryWriteWrites a value to the Registry.
ScriptExecutes code contained within the task.
ServiceControllerTask that can control a Windows service.
ServiceQueryTask that can determine the status of a service.
SleepA task for sleeping for a specified period of time.
SqlExecuteExecutes a SQL command
SvnCheckoutCheckout files from Subversion
SvnClientSubversion Client
SvnCommitCommit files to Subversion
SvnExportExport files from Subversion
SvnInfoGet Subversion information for a file or directory.
SvnUpdateUpdate files from Subversion
SvnVersionGet Subversion revision number of a local copy
TaskSchemaGenerates a XSD schema of the MSBuild tasks in an assembly.
TimeGets the current date and time.
UnzipUnzip a file to a target directory.
VersionIncrements a four-part version number stored in a text file
VssAddAdds files to a Visual SourceSafe database.
VssCheckinChecks in files to a Visual SourceSafe database.
VssCheckoutChecks out files from a Visual SourceSafe database.
VssCleanRemoves Visual SourceSafe binding information and status files from a Visual Studio solution tree.
VssDiffGenerates a diff between two versions of an item in a Visual SourceSafe database.
VssGetGets the latest version of a file or project from a Visual SourceSafe database.
VssHistoryGenerates an XML file containing the history of an item in a Visual SourceSafe database between two dates or labels.
VssLabelLabels an item in a Visual SourceSafe database.
VssUndoCheckoutCancels a checkout of an item from a Visual SourceSafe database.
WebDirectoryCreateCreates a new web directory on a local or remote machine.
WebDirectoryDeleteDeletes a web directory on a local or remote machine
WebDownloadDownloads a resource with the specified URI to a local file.
XmlReadReads a value from a XML document using a XPath.
XmlWriteUpdates a XML document using a XPath.
XsltMerge and transform a set of xml files.
ZipCreate a zip file with the files specified.

Join Project

Please join the MSBuild Community Tasks Project and help contribute in building the tasks. 


Create a Relative path code snippet

Here is a code snippet that is equivalent to the windows API PathRelativePathTo as native c#. The function creates a relative path from one file or folder to another.

public class PathUtil  
{  
    /// <summary>  
    /// Creates a relative path from one file  
    /// or folder to another.  
    /// </summary>  
    /// <param name="fromDirectory">  
    /// Contains the directory that defines the   
    /// start of the relative path.  
    /// </param>  
    /// <param name="toPath">  
    /// Contains the path that defines the  
    /// endpoint of the relative path.  
    /// </param>  
    /// <returns>  
    /// The relative path from the start  
    /// directory to the end path.  
    /// </returns>  
    /// <exception cref="ArgumentNullException"></exception>  
    public static string RelativePathTo(  
        string fromDirectory, string toPath)  
    {  
        if (fromDirectory == null)  
            throw new ArgumentNullException("fromDirectory");  
   
        if (toPath == null)  
            throw new ArgumentNullException("toPath");  
   
        bool isRooted = Path.IsPathRooted(fromDirectory)  
            && Path.IsPathRooted(toPath);  
   
        if (isRooted)  
        {  
            bool isDifferentRoot = string.Compare(  
                Path.GetPathRoot(fromDirectory),  
                Path.GetPathRoot(toPath), true) != 0;  
   
            if (isDifferentRoot)  
                return toPath;                           
        }                 
   
        StringCollection relativePath = new StringCollection();  
        string[] fromDirectories = fromDirectory.Split(  
            Path.DirectorySeparatorChar);  
   
        string[] toDirectories = toPath.Split(  
            Path.DirectorySeparatorChar);  
   
        int length = Math.Min(  
            fromDirectories.Length,  
            toDirectories.Length);  
   
        int lastCommonRoot = -1;  
   
        // find common root  
        for (int x = 0; x < length; x++)  
        {  
            if (string.Compare(fromDirectories[x],  
                toDirectories[x], true) != 0)  
                break;  
   
            lastCommonRoot = x;  
        }  
        if (lastCommonRoot == -1)  
            return toPath;  
   
        // add relative folders in from path  
        for (int x = lastCommonRoot + 1; x < fromDirectories.Length; x++)  
            if (fromDirectories[x].Length > 0)  
                relativePath.Add("..");  
   
        // add to folders to path  
        for (int x = lastCommonRoot + 1; x < toDirectories.Length; x++)  
            relativePath.Add(toDirectories[x]);  
   
        // create relative path  
        string[] relativeParts = new string[relativePath.Count];  
        relativePath.CopyTo(relativeParts, 0);  
   
        string newPath = string.Join(  
            Path.DirectorySeparatorChar.ToString(),  
            relativeParts);  
   
        return newPath;  
    }  
}  

Draco.NET version 1.6.4.0 Released

I’ve update and released a new version of Draco.NET. This release is mainly to make it compatible with Visual Studio 2005 and MSBuild. The following is a list of changes …

1.6-release-2 (1.6.4.0)

  • Added MSBuild support
  • Added Visual Studio 2005 support
  • Added manual build (no polling) support
  • Improved project config web page
  • Fixed bug where error emails were sent repeatedly

What is Draco.NET?

Draco.NET is a Windows service application designed to facilitate continuous integration. Draco.NET monitors your source code repository, automatically rebuilds your project when changes are detected and then emails you the build result along with a list of changes since the last build.