Saturday, February 14, 2009

Debug Classic ASP in Visual Studio 2008

It is a little bit tricky to debug classic ASP in Visual Studio 2008 so I decided to document it. There are many articles that describes it, but this is how I managed to get it to work.
Visual Studio 2008 Service Pack 1 must be installed, it adds debugging and IntelliSense functionality for classic ASP.
Then the IIS must be configured to allow debugging, on both client- and server-side. Remember also to set Send Errors To Browsers to True if the ASP is hosted in IIS7.
image

Now open Your ASP project in Visual Studio and set the local IIS as Web server:

image

Ok, then its time to debug. Open Your ASP-page in Windows Explorer. Then attach the VS2008 debugger to the IIS hosting process, i.e. select Debug->Attach to Process... and attach to the dllhost.exe if running on IIS6 or w3wp.exe if running on IIS7.
If there are multiple processes, pick the one with Script type.

The Attach to: should be set to Script code.

(The Show processes from all users must be checked to see the hosting processes)

image

Add some breakpoints, hit the F5 to reload the web-page and now should the debugger stop at your breakpoints.

Important: Visual Studio often crashes when ending a debug-session. If that happens, kill the dllhost.exe/w3wp.exe to avoid unpredictable errors.

Monday, February 9, 2009

Convert ADO Stream and Recordset to XML

When working with older applications, i.e. pre-.NET, its helpful with functions that converts ADO Streams and Recordset to XML and vice versa. Especially when older applications should be migrated or communicate with .NET applications and its prefered to rewrite as little as possible. Another approach would be to use JSON.

Anyway, here are a couple of converting functions that are useful.

Recordset <-> XML
/// <summary>
/// Convert XML to recordset
/// </summary>
/// <param name="sXML"></param>
/// <returns>Recordset</returns>
public static Recordset recordsetFromXML(string sXML)
{
    if (string.IsNullOrEmpty(sXML))
    {
        // Nothing to convert
        return null;
    }

    // Open an ADO Stream
    var oStream = new Stream();
    oStream.Open(Missing.Value, ConnectModeEnum.adModeUnknown,
                 StreamOpenOptionsEnum.adOpenStreamUnspecified,
                 "", "");

    // Load the XML string into stream
    oStream.WriteText(sXML, StreamWriteEnum.adWriteChar);
    oStream.Position = 0;

    // Create empty recordset
    var oRecordset = new Recordset();

    // Read the XML stream
    oRecordset.Open(oStream, Missing.Value,
                    CursorTypeEnum.adOpenUnspecified,
                    LockTypeEnum.adLockUnspecified, 0);
    oStream.Close();

    //Return the recordset
    return oRecordset;
}

/// <summary>
/// Convert recordset to XML
/// </summary>
/// <param name="oRecordset"></param>
/// <returns>String</returns>
public static string recordsetToXML(Recordset oRecordset)
{
    string xmlString = "";

    if (oRecordset != null)
    {
        // Load recordset into stream
        var oStream = new Stream();
        oRecordset.Save(oStream, PersistFormatEnum.adPersistXML);

        // Get the XML
        xmlString = oStream.ReadText(oStream.Size);
    }

    return xmlString;
}
Stream <-> XML
/// <summary>
/// Convert XML to stream
/// </summary>
/// <param name="sXML"></param>
/// <returns>Stream</returns>
public static Stream streamFromXML(string sXML)
{
    // Load XML into XmlDocument
    var oXML = new XmlDocument();
    oXML.InnerXml = sXML;

    // Get the STREAM element
    var aNode = oXML.GetElementsByTagName("STREAM")[0];

    // Create a binary stream
    var oStream = new Stream();
    oStream.Type = StreamTypeEnum.adTypeBinary;
    oStream.Open(Missing.Value, ConnectModeEnum.adModeUnknown,
                 StreamOpenOptionsEnum.adOpenStreamUnspecified,
                 "", "");

    // Load XML
    oStream.Write(Convert.FromBase64String(aNode.InnerXml));
    oStream.Position = 0;

    return oStream;
}

/// <summary>
/// Convert stream to XML
/// </summary>
/// <param name="oStream"></param>
/// <returns>String</returns>
public static string streamToXML(Stream oStream)
{
    // Create XmlDocument
    var oXML = new XmlDocument();
    oXML.AppendChild(oXML.CreateProcessingInstruction("xml", "version='1.0'"));

    // Add STREAM element to hold the binary data
    XmlElement oElem = oXML.CreateElement("STREAM");

    // Define type of value
    XmlAttribute dt = oXML.CreateAttribute("dt", "dt", "urn:schemas-microsoft-com:datatypes");
    dt.Value = "bin.base64";
    oElem.SetAttributeNode(dt);

    // Convert stream data to string
    oElem.InnerXml = Convert.ToBase64String((byte[])oStream.Read(-1));
    oXML.AppendChild(oElem);

    // Return Xml
    return oXML.InnerXml;
}