all posts

WhatIWantMost Adding RSS and Inviting Friends

Published to Blog on 5 Mar 2007

Up to this point in the development of the WhatIWantMost project I have chosen to implement the simplest solution possible to complete each task (or at least that I could think of) and that will not end today. That approach is of course a bastardization of the one of core values of XP. To borrow a phrase from a colleague, whether you choose to swallow the Agile pill or not is entirely up to you, but some of the goals, beliefs and tenets just make sense. Simplicity, Communication and Feedback are all important. Accepting change just makes your life easier. And processes adopted and promoted by the Agile community like unit testing, acceptance testing, and continuous integration have found their place in more traditional development approaches as well.

Let’s get back to my current point, though. I have chosen the simplest approach to make it work. I chose to use .netTiers as a persistence mechanism and to serve as the core of the site. .netTiers and CodeSmith are not simple tools, but using them effectively is fairly simple for any developer that’s been around the block a time or two. I simply created a database model that would support the actors and functionality that I envisioned for the site, pressed a couple of buttons and my API was generated for me. To simplify my URLs and in many cases to point multiple URLs to one physical file I chose to implement another off-the-shelf tool, UrlRewritingNet.UrlRewrite. I chose to use the Amazon, Yahoo, Windows Live, and Ebay APIs to implement product and web searches.

Over the last few evenings I implemented a couple of the remaining items on my task list, adding the ability for users to invite others to view their wishlist and/or join the site, adding some caching for data frequently displayed on the site, and adding RSS feeds. I think I’ve probably shown enough examples to demonstrate how easy it is to work with .netTiers, but I know how much Dave Burke likes those examples so I will show one more. To create the support for the referral functionality I had to add a new table to my database that looks something like this:

Table: Referral
  Fields:
    PK ID int
    FK UserID uniqueidentifier
    DateCreated datetime
    FirstName string
    LastName string
    EmailAddress string
    DateJoined datetime
    ReferralUserID uniqueidentifier

The DateJoined and the ReferralUserID field will be used to record if the invited user later becomes a member of the site. The UserID field records the id of the person creating the invite and the rest of the fields belong to person being invited and should be self explanatory. After creating that, running the .netTiers template on the database again and putting my newly created files in place all I had to do was create a simple web form and then add some code like this to handle those invitations:

Referral referral = new Referral();
referral.FirstName = txtFirstName.Text;
referral.LastName = txtLastName.Text;
referral.EmailAddress = txtEmail.Text;
referral.UserID = new Guid(CurrentUser.ProviderUserKey.ToString());
ReferralService.Insert(referral);
Email.SendReferral(referral.FirstName, referral.LastName,
  referral.EmailAddress, CurrentUser.UserName,
  txtMessage.Text);

Most of the above code makes use of the .netTiers generated API: I create a new referral, set the properties based on those filled into the form and then insert the referral into the database using the ReferralService.Insert() method. The final line of code makes use of an email utility class that I tend to add to most of my web projects to encapsulate all the email code. The email class is made up of mostly static methods and currently there are only two of them: Send(toaddress, fromaddress, subject, body) and the SendReferral(…) method shown above. The SendReferral method makes use of an email template, fills in the passed in data and then just calls the Send() method.  All the email setup, retrieval of email server settings, and teardown are encapsulated in that utility class.

To add caching for Featured Items, Popular Items, New Members, Recently Updated Wishlists, etc. I added a controller class to mediate requests for those items from the .netTiers generated API. It firsts checks to see if those items are cached and if not then it requests them from the API. For caching I chose to keep it simple and use the System.Web.Caching.Cache object - there’s no need to create a wrapper or my own framework for the simple things I need done. I double-checked to make sure I was following Scott’s State Management tips and it looks like I’m compliant. Each of the items mentioned above are displayed on almost every page of the site. Even though what I’m pulling from the database for each of those is rather lightweight the performance gains after implementing the caching are noticeable.

Finally, to implement RSS I chose to use a combination of pointing all the “virtual” RSS feeds to one physical page using the Url rewriter and RSS.NET to write out the feeds.  I currently only have a small number of feeds and I really don’t foresee needing much more so it made sense to handle them all in one place. Below are some example rss feed urls that all actually point to the file http://whatiwantmost.com/rss.aspx:

http://whatiwantmost.com/popular/Rss.aspx
http://whatiwantmost.com/hotgiftidea/Rss.aspx
http://whatiwantmost.com/recentmembers/Rss.aspx
http://whatiwantmost.com/wishlist/bobby/Rss.aspx

I chose to use RSS.NET because I’ve used it before and it works well. There’s no reason for me to create the code to write out my own RSS feeds when there is a tool available that does it. For the data to create the feeds I made use of the mediator class and the cached objects that I described above. The logic for displaying the feeds just needs to determine what feed it is supposed to be displaying, get the objects to display, and then use RSS.NET to display them. Following is example code showing getting the set of data to display (Popular Items in this case) and using the RSS.NET API:

RssChannel channel = new RssChannel();
List<PopularItem> items = Controller.PopularItems;
foreach (PopularItem item in items)
{
  RssItem rssItem = new RssItem();
  rssItem.Title = item.Itemname;
  rssItem.Description = item.Description;
  rssItem.Link = new Uri(UrlProvider.GetAmazonItemUrl(item.AmazonID));
  rssItem.PubDate = (DateTime)item.DateAdded;
  channel.Items.Add(rssItem);
}
channel.Title = "WhatIWantMost Popular Items";
channel.Description = "The most popular items on WhatIWantMost.";
channel.LastBuildDate = channel.Items.LatestPubDate();
RssFeed feed = new RssFeed();
feed.Channels.Add(channel);
Response.ContentType = "text/xml";
feed.Write(Response.OutputStream);
Response.End();

You can see in the code above that creating the RSS feed is a fairly simple process. I create the channel, get the data to display, loop through the data creating an RSSItem for each one, add each item to the channel, create an RSSFeed, add the channel to the feed and then write it all out to the page.

To date I have most of the original items crossed off my todo list other than reviews, some profile editing and printer friendly pages. Some new functionality has squeezed its way into the list since we started this project, but for now it will have to wait at the back of the line. I would guess that I am about 90% feature complete and about 75% complete with the first phase of the project. I’ve also realized that I still need to write some copy for pages in addition to things like the FAQ, Feedback forms, Privacy Policy, Terms and Conditions, etc. Right now the site is functional enough to put up for some feedback. In my next post I hope to announce that WhatIWantMost  (Alpha) is live and available for you to poke at if you’d like.


Dan Hounshell
Web geek, nerd, amateur maker. Likes: apis, node, motorcycles, sports, chickens, watches, food, Nashville, Savannah, Cincinnati and family.
Dan Hounshell on Twitter


  • On 6 Jul 2007 "Digging My Blog - Dan Hounshell"" said:
    Following is a list of all the posts of the WhatIWantMost series. I'm listing them all here mostly for
  • On 7 Jul 2007 "Dave Burke"" said:
    I'm a little slow here, but saw your complete WhatIWantMost list post and was interested in your RSS implementation. WIWM is lookin' good! I want to spend more time there. I need to blog about CodeSmith soon, as I'm doing some sweet CS code-genning with it. I pulled up the .netTiers .CSTs just yesterday to study them a bit. Ahh, so much good stuff there. Thanks for the excellent examples. -)
  • On 7 Jul 2007 """ said:
    Thanks, Dave. The various RSS implementations are all about the same - based on the code above. I like subscribing to the Latest Members and Recently Updated Wishlists so that I can keep an eye on the site. However, the coolest RSS feeds by far, as far as I am concerned, is the ability to subscribe to an individual's wishlist. I think that one will be the most useful for the site's members.