daGrind
22May/070

Internet Explorer 7, Outlook 2007, Windows RSS Platform

I do not know everything about this topic, but here are some of my thoughts from my experiences. I really enjoy listening to Hansel Minutes and .NET Rocks! on my Zune as I code or commute. The ability to download enclosures from an RSS feed is great and can make keeping the task of keeping my Zune synced up with the latest episodes a breeze. You can configure IE 7 to download enclosures automatically.

Configure IE 7 Feed Enclosure Downloads
1. Subscribe to a feed that offers enclosures in IE 7, like .NET Rocks!:
http://www.pwop.com/feed.aspx?show=dotnetrocks&filetype=master
2. Open the Favorites Center and click on the Feeds tab.
3. Right-click on the feed that you subscribed to in the first step and click on the "Properties..." menu option.
4. Click on the "Automatically download attached files".
5. Click on the OK button.

The feed's enclosures will be automatically downloaded the next time that the feed is checked. The following directories are where the feeds and enclosures are stored on Windows Vista.

Feeds (.feed-ms)
C:\Users\username\AppData\Local\Microsoft\Feeds

Enclosures
C:\Users\username\AppData\Local\Microsoft\Windows\Temporary Internet Files\Enclosure\{76E975B3-71EA-4820-85D6-BB6D878879E3}

I do not like that the enclosures are stored in the "Temporary Internet Files" directory and that this location is not configurable. The enclosure files are not deleted when you use the "Delete Browsing History" dialog to delete all browsing history. So you could configure your Zune to sync files with any the Enclosure directory or a specific GUID enclosure directory. You can find the enclosure directory name for a specific feed by clicking on the "View Files" button next to the "Automatically download attached files" checkbox described in step 4 (configuring feed enclosure downloads). I know that I could write a FileSystemWatcher or use the COM object provided by the Windows RSS Platform to setup events to monitor the downloading of enclosures. This seems like a lot of work for something that in my opinion should be configurable in the feeds properties dialog. I know that you can use the Outlook 2007 "Sync RSS Feeds to the Common Feed List" option and also enable the downloading of enclosures. The enclosures downloaded in Outlook 2007 are stored in a .PST file. I have also read about issues with very large personal folder files in Outlook 2007 where the size is greater than 2GB in size. The .PST file for a feed like .NET Rocks! would easily be larger than 2GB and could possibly cause performance issues in Outlook 2007. It would have been nice if IE7 and Outlook 2007 would have both used the same store instead of smoke and mirrors to "sync" the feeds.

Conclusion
I like the ability to use IE7 and Outlook 2007 to manage my RSS subscriptions, since I already use both of those applications daily. I am not a huge fan of installing other software that is only going to bloat my system, especially those that need to auto start or run as services and will consume extra memory or CPU resources that I would rather leave for more productive work. The only complaint that I have currently with either is how enclosures are handled, but IE7 does offer a way for me to get at the enclosures. I have more thoughts on this subject and will post more information about those thoughts as I have time.

Alternatives
There are really good RSS readers that allow you to configure the directory that enclosures should be downloaded into like RSS Bandit and Attensa.

Tagged as: No Comments
15May/072

Workbench #4 & Crib #1

Here is a picture of the finished workbench and all of the hard maple after being dimensioned to the correct thickness.


14May/070

XmlSiteMapProvider – Query String Support

Most of the ASP.NET applications that I create have some type of a menu and the menu is typically dynamic. When I say dynamic I mean that the menu items are usually dependent on the user's current location in the application and sometimes require query strings (i.e. the Id of a photo album). The default XmlSiteMapProvider is nice and can be very useful coupled with the securityTrimmingEnabled attribute (the provider model is very awesome...thank you Rob Howard). However, the default XmlSiteMapProvider does not offer any support for query strings. I wanted a solution that would allow me to use the existing .sitemap format, automatically adding query strings to menu items, hide menu items if those query strings were not available, and did not require creating any custom controls. I first looked at the SiteMapProvider.SiteMapResolveEventHandler event, but this option would only work if I was using the SiteMapPath control. I then decided to see what was overridable in XmlSiteMapProvider since that provider did exactly what I wanted with the exception of handling query strings. I came up with the class below that handles all of my requirements and simply added the new provider to the SiteMap providers in the web.config. You can download a small sample application here.

using System;
using System.Web;
using System.Collections.Specialized;

public class XmlQueryStringSiteMapProvider : XmlSiteMapProvider
{
    /// Gets the root node of the site map.
    public override SiteMapNode RootNode
    {
        get
        {
            // Get the root node
            SiteMapNode root = base.RootNode;

            // Make sure we have a valid root node object
            if (root == null)
                return null;

            // Clone the root node
            SiteMapNode tempNode = root.Clone();

            // Check to see if this node requires a query string
            string qs = GetQueryString(tempNode);
            if (!string.IsNullOrEmpty(qs))
                tempNode.Url += qs;

            return tempNode;
        }
    }

    /// Retrieves the child site map nodes of a specific SiteMapNode object.
    public override SiteMapNodeCollection GetChildNodes(SiteMapNode node)
    {
        // Make sure we have a valid node
        if (node == null)
            throw new ArgumentNullException("node");

        // Build the site map
        this.BuildSiteMap();

        // Get a collection of all child nodes
        SiteMapNodeCollection collection = base.GetChildNodes(node);

        // Make sure we have a vlid collection of child nodes
        if (collection == null)
            return new SiteMapNodeCollection();

        // Create a new collectino that will hold the final nodes
        SiteMapNodeCollection nodes = new SiteMapNodeCollection(collection.Count);
        foreach (SiteMapNode n in collection)
        {
            // Clone the current node
            SiteMapNode tempNode = n.Clone();

            // Make sure this node is accessible
            if (base.SecurityTrimmingEnabled && !n.IsAccessibleToUser(HttpContext.Current))
                continue;

            // Check to see if this node requires a query string
            string qs = GetQueryString(tempNode);
            if (!string.IsNullOrEmpty(qs))
                tempNode.Url += qs;
            else if (n["required"] == "true" && !string.IsNullOrEmpty(n["queryString"]))
                continue; // DO not add this node to the collection

            nodes.Add(tempNode);
        }

        return SiteMapNodeCollection.ReadOnly(nodes);
    }

    /// Creates a query string based on the node settings.
    private string GetQueryString(SiteMapNode node)
    {
        // Check to see if this node requires query string values
        if (node["queryString"] == null)
            return null;

        // Get a list of the query string names
        NameValueCollection values = new NameValueCollection();
        string[] vars = node["queryString"].Split(",".ToCharArray());

        // Check to see if we have values for the query string names
        foreach (string s in vars)
        {
            string var = s.Trim();

            // Check to see if the query string value exists
            if (HttpContext.Current.Request.QueryString[var] == null)
                continue;

            // Add the query string value to the collection
            values.Add(var, HttpContext.Current.Request.QueryString[var]);
        }

        if (values.Count == 0)
            return null;

        // Build the query string
        string[] parts = new string[values.Count];

        for (int i = 0; i < values.AllKeys.Length; i++)
            parts[i] = values.AllKeys[i] + "=" + values[values.AllKeys[i]];

        return "?" + String.Join("&", parts);
    }
}
5May/070

Visual Studio 2005 – Recent Projects (Update)

I have updated the Recent Projects tool that I created to support Orcas. You can download the Recent Projects application here.

2May/070

Silverlight 1.0 Beta – Hello World

Here is my first Silverlight 1.0 Beta page. Orcas is finishing installing as we speak and then I have a few ideas that I would like to implement using Silverlight 1.1 Alpha. I experienced the same issue and resolution that Rick Strahl has documented in his blog entry.

UPDATE: Removed the link to my Silverlight 1.0 Beta.

1May/070

Visual Studio 2005 – Recent Projects

I do not know about you, but I like to have full control over everything and it drives me crazy that Visual Studio 2005 does not offer an easy way to delete items from the Recent Projects list on the start page from within the IDE. I did a little looking around and see that the list of projects is stored in the registry.

Visual Studio 2005
HKCU\Software\Microsoft\VisualStudio\8.0\ProjectMRUList

Microsoft Visual C# 2005 Express Edition
HKCU\Software\Microsoft\VCSExpress\8.0\ProjectMRUList

Visual Web Developer 2005 Express Edition
Software\Microsoft\VWDExpress\8.0\ProjectMRUList

I created a very simple .NET 2.0 windows application that allows you to delete specific projects or clear an entire list of projects for a specific version of Visual Studio 2005. This is really nice because the key names must be sequential named/numbered (i.e. File1, File2, File2). Who wants to go into regedit and manually rename "File3" through "File10" after deleting "File2"? This application makes managing the recent project lists a quick and painless task. You can download the Recent Projects application here. Please feel free to download and use this application. This application requires Windows and the .NET Framework 2.0.

I am downloading the bits for Orcas Beta 1 and will see if they have addressed this issue or if I need to add support to my Recent Projects application.