ASP.NET MVC 2 RTM is now available for download!

It’s here! You can now download the release version of ASP.NET MVC 2here.

For more Information check out this post on Phil Haack’s blog.

ScottGu also has a post outlining the new features.

So to the good stuff, What’s new?

When creating a new project the default route now uses UrlParameter.Optional instead of an empty string for the id parameter.

In previous versions of ASP.NET MVC, the default route looked like this:

routes.MapRoute(
         "Default", // Route name
         "{controller}/{action}/{id}", // URL with parameters
         new { controller = "Home", action = "Index", id = "" } // Parameter defaults
     );

This can cause problems for views that create objects. Since we don’t have an id on the create, we want that field to be null so our data layer knows it’s a new object. The workout before was to use [Bind(Exclude = “ID”)] in the action method to explicitly tell the framework to not bind the id field.

Now, out of the box, the default route  looks like this:

routes.MapRoute(
         "Default", // Route name
         "{controller}/{action}/{id}", // URL with parameters
         new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
     );

We no longer have to worry about excluding the id property binding.

You can read more about it here.

Another new addition is the ability to add optional view data when using templated helpers. You can pass in extra view data as an anonymous object and it gets added to the existing view data object in the templated helper.

For example, in my main view I can render the display template by doing something like this:

<%=Html.DisplayFor(m=>m,new {Foo="bar"})%>

I’m now passing Foo as an additional view data. It is accessible in the templated helper through the following syntax:

<%=ViewData["Foo"]%>

Overall I’m pretty excited by this release of ASP.NET MVC 2. I’ve been using it for a while now and I’m very happy with it and all the great it new features it has. I’m looking forward to future releases and all the cool new features it’s going to have.

Advertisements

Consuming an RSS Feed with ASP.NET MVC

In this post I’m going to show you how to consume an RSS feed and display it on your website. This post is going to assume you already know the basics of ASP.NET MVC, such as how to create controllers and views. If you’re not too familiar with ASP.NET MVC, I suggest you read this tutorial first.

Before we get started, we need an RSS feed url. Since this is about ASP.NET MVC I decided to go with, Phil Haack’s Blog. Phil is a Senior Program Manager at Microsoft on the ASP.NET team. The feed url for his blog is http://feeds.haacked.com/haacked

In order to consume an RSS Feed we need a utility to pull the xml off the web and parse it. We could write our own RSS reader from scratch. The RFC is available and should outline everything you need. Luckily for us, there is an open source project that does just that. The ASP.NET RSS Toolkit is a great tool that will make this an almost trivial task.

Download the RSS Toolkit zip file and extract it. You should find several folders, go into the RssToolkit folder and grab RssToolkit.dll from the Bin->Release.

In your ASP.NET MVC project create a folder called lib and drag RssToolkit.dll into the lib folder. Technically you don’t have to do this step, but I like to house any external dll’s I use with my project.

Add a reference to the dll in the references section by right clicking on the References tab and selecting “Add Reference” Then go to the “Browse” tab and select RssToolkit.dll (remember it’s in the Lib folder.)

Let’s jump into some code. We could add the RSS functionality into our HomeController or any existing controller. For this example let’s add a Feed Controller to our project. At the top of the file make sure you add a using statement to pull in the RssToolkit.Rss namespace.

using RssToolkit.Rss;

There should already be an a default Index action method in the Feed Controller. In the Index action method we’re going to instantiate an RssDocument object by calling it’s static load method and passing it a Uri object with Phil’s Feed Url.

RssDocument rss = RssDocument.Load(new Uri("http://feeds.haacked.com/haacked"));

After this all we have to do is pass a collection of RssItems to our view for rendering. All the RssItems are found in the RssDocument Channel object instance.

return View(rss.Channel.Items);

Now let’s create our view by right clicking on the Index method and selecting “Add View” . Let’s make it a strongly typed view of type RssToolkit.Rss.RssItem. Also, lets select the “List” View content type so that our view is an IEnumerable<RssItem>

That’s it! Build and run the application and you should see a table with a list of rss feed items. Warning: It’s going to be ugly. Since the data is not tabular in nature, it’s going to look a little funny. Also, because asp.net mvc’s list template automatically html encodes all fields, the description column will have no formatting and the html tags will be visible.

Let’s make it look a little nicer. Instead of a table, we should use div’s and style them up using css.

Since this is just a demo I’m going to add the css directly into the view’s header section (ideally you want to place it in an external css file and include it). Replace the header section of your view with the following:

<head runat="server">
    <title>Index</title>
    <style type="text/css">
      .RssItemTitle,.RssItemTime,.RssItemDescription
      {
          font-family:Arial;
      }
      .RssItemTitle a
      {
          font-size:20px;
          font-weight:bold;
          text-decoration:none;
      }
      .RssItemTime
      {
        font-size:12px;
      }
    .RssItemDescription
    {
        font-size:14px;
        padding-bottom:15px;
        margin-bottom:15px;
        border-bottom:2px solid black;
    }
    </style>
</head>

Now, let’s change the code that renders our RssItem to the following:

<%foreach (var item in Model) { %>
<div>
   <div class="RssItemTitle">
       <a href="<%=item.Link%>" target="_blank"><%=Html.Encode(item.Title)%></a>
   </div>
   <div class="RssItemTime">
       <%=Html.Encode(String.Format("{0:M} - {0:t}", item.PubDateParsed.ToLocalTime()))%>
   </div>
    <div class="RssItemDescription">
        <%=item.Description%>
    </div>
</div>
<%}%>

Notice, instead of a table we’re now using div tags and applying css classes to it. For the post title we’re making it a link back to the original post and styling it so that it won’t be underlined and making it a slightly larger font. The Time field is simply smaller and the description (the actual body of the post) will be a slightly bigger font and will include a line after each description (to separate posts).

Save you view and reload the website in your browser. You should see a much nicer result.

There one important thing I have to point out. We’re not Html Encoding the item description (the body of the post). This is because it often it contains html formatting such as links or image tags and we want to carry all of that through. However, this can lead to a security hole, so please only pull information from feeds that you trust. A malicious blogger could easily add javascript into a feed post and take control of your site. You can also create your own filter that would still allow html formatting tags, but remove any of the dangerous javascript and/or hidden form posts.

This example was a basic introduction into how to read an RSS Feed in Asp.net MVC. There are a couple of problems with our implementation though, we are tightly coupled to the RssToolkit. If we later find a different RSS library or decide to write our own, we need to do some significant re-writing of our website. Ideally we want to encapsulate all this so we can easily swap out RSS implementations without any significant impact to our site. In a follow up post I’m going to take this example and try to make more resilient to change by implementing some good architectural practices. So stay tuned!

Download the sample project for this post. (Note I created this project using asp.net mvc 2 rc, but you can easily recreate it in asp.net mvc 1)