Freigeben über


RSS Feed with the new ASP.NET MVC Framework

I thought I'd add my own MVC example to the great work that ScottGu and Hanselman have already outlined...     I know folks are ready to get their hands on these bits and believe me the team is working hard to get them out in a public CTP as soon as we can.. In the mean time, you will have to settle for these teasers ;-) 

 

In this example, I am going to walk through building an RSS feed from data in a relational database..  My goal here is to give you and idea of what is possible with the MVC support that is coming out as a CTP soon for ASP.NET...

 

File/New Project and select the MVC Project item

image

There is some good stuff here, that really shows you how to get going... but for what we are going to do, we don't really need it...  so go ahead and clear out all the directories and files under Views, Models and Controllers... we will build this from scratch.

 

Creating the Model

Because I had an existing database, I chose to start with it...  I added my VideoDatabase.mdf file from another project I worked on recently.. of course any database would work.  Then I created a Linq model and called it "VideoDatabase.dbml"... Notice of course EntityFramework would work really well here as well... 

image

In the LINQ designer, I added the Items table to the design surface

image

and then moved the resulting VideoDatabase.dbml file to the Models directory... We now have our model done! 

 

Creating the Controller

Next we add our controller which handles the UI logic of our application..  I click on the Controllers folder and Add new item

image

I called it FeedController, but remember, this has to end in Controller as there are some conventions we use to find these types.. I added the following code to get the list of items from the database and pass it to the view...

    public class FeedController : Controller

    {

        //example: https://localhost:64701/

        [ControllerAction]

        public void Index()

        {

            VideoDatabaseDataContext context = new VideoDatabaseDataContext();

            var list =

                from item in context.Items

                orderby item.Title

                select item;

            RenderView("Feed", list.ToList());

        }
}

(note: be sure to add using MvcApplication.Models)

 

Creating the View

The view we want for an RSS feed is actually an not HTML... it is an XML file... but we want to programmatically generate it.  I started by creating a new directory called "Feed" under "View" and added an MVC View Page called "Feed"... 

image

Then I went to my blog and grabbed the RSS feed to use as an example.  You can create a temporary XML file in VS to view it cleanly, then strip all but one entry...   You will end up with something like this:

image

Next we need to parameterize this to use the data from our Model... 

The first thing to do to enable that is to type the ViewData this page will work with.. you do that by going into the codebehind and setting the base class to be associated with the Item from our Model...  

namespace MvcApplication.Views.Feed

{

    public partial class Feed : ViewPage<IList<Item>>

    {

    }

}

(note: be sure to add using System.Collections.Generic and using MvcApplication.Models)

Then, back in the feed.aspx page, you can access the view data... right before the open <item> add the start of a foreach loop, then close it after the end...

<%  foreach (Item item in this.ViewData) { %>

 

    <item>

Then, replace each value with the appropriate data from the view programmatically... 

<link><%= item.VideoLink%> </link>

What you end up with looks like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Feed.aspx.cs" Inherits="MvcApplication.Views.Feed.Feed" %>

<%@ Import Namespace="MvcApplication.Models" %>

<%@ Import Namespace="System.Collections.Generic" %><?xml version="1.0" encoding="utf-8"?>

<rss version="2.0" xmlns:atom="https://www.w3.org/2005/Atom" xmlns:cf="https://www.microsoft.com/schemas/rss/core/2005" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/" xmlns:wfw="https://wellformedweb.org/CommentAPI/">

  <channel xmlns:cfi="https://www.microsoft.com/schemas/rss/core/2005/internal" cfi:lastdownloaderror="None">

    <title cf:type="text"> MySilverlightTV Feed</title>

    <link>https://blogs.msdn.com/brada/default.aspx</link>

    <description cf:type="text">Check out the latest videos from MySilverlightTV</description>

    <dc:language>en-US</dc:language>

    <generator>MVC RSS</generator>

 <% foreach (Item item in this.ViewData) { %>

 

    <item>

      <title xmlns:cf="https://www.microsoft.com/schemas/rss/core/2005" cf:type="text">

        <%= item.Title %> </title>

      <link><%= item.VideoLink%> </link>

      <pubDate><%= DateTime.Now.ToFileTimeUtc() %> </pubDate>

      <author><%= item.Owner%> </author>

      <description xmlns:cf="https://www.microsoft.com/schemas/rss/core/2005" cf:type="html">

        <%= item.Description %>

      </description>

    </item>

 <% } %>

  </channel>

</rss>

 

 

Run it

We want to navigate to the Controller we created..  so navigate to https://localhost:64701/feed

and you get this beautiful RSS feed ready to work in any blog reader:

image

 

But there is more

Of course there is was only a few lines of code here, but really I could have done this just as easily, what does all that MVC stuff buy you?    Well, a good architecture for one, and that means it is super flexible.  So when you need to add a different feed, say the most popular items, or the new items added, or the top 10 items, it is very easy to do...  Here are a few more items I added by only touching the controller, everything else stayed the same:

 

    public class FeedController : Controller

    {

        //example: https://localhost:64701/

        [ControllerAction]

        public void Index()

        {

            VideoDatabaseDataContext context = new VideoDatabaseDataContext();

            var list =

                from item in context.Items

                orderby item.Title

                select item;

            RenderView("Feed", list.ToList());

        }

        //example: https://localhost:64701/feed/Top10

        [ControllerAction]

        public void Top10()

        {

            VideoDatabaseDataContext context = new VideoDatabaseDataContext();

            var list =

                from item in context.Items

                orderby item.Rating

                select item;

            RenderView("Feed", list.Take(10).ToList());

        }

        //example: https://localhost:64701/feed/Top?n=2

        [ControllerAction]

        public void Top(int n)

        {

            VideoDatabaseDataContext context = new VideoDatabaseDataContext();

            var list =

                from item in context.Items

                orderby item.Rating

                select item;

            RenderView("Feed", list.Take(n).ToList());

        }

        //example: https://localhost:64701/feed/FromMSFT

        [ControllerAction]

        public void FromMSFT()

        {

            VideoDatabaseDataContext context = new VideoDatabaseDataContext();

            var list =

                from item in context.Items

                orderby item.Title

                where item.Owner == "MSFT"

                select item;

            RenderView("Feed", list.ToList());

        }

        //example: https://localhost:64701/feed/FromPublisher?Publisher=WildAmerica

        [ControllerAction]

        public void FromPublisher(string publisher)

        {

            VideoDatabaseDataContext context = new VideoDatabaseDataContext();

            var list =

                from item in context.Items

                orderby item.Title

                where item.Owner == publisher

                select item;

            RenderView("Feed", list.ToList());

        }

    }

 

 

What do you think?  are we on the right track?

Comments

  • Anonymous
    November 14, 2007
    Looks good but don't forget encoding your output! I keep seeing examples that don't bother ("it's just a sampe") which means developers will think they don't have to either and we're going to end up in a world of cross-site scripting pain! Unless MVC is going to encode it for us... [)amien

  • Anonymous
    November 14, 2007
    The new MVC stuff is definitely on the right track, but this doesn't take it far enough. Feeds are common enough that there should be a RenderFeed(Feed) method which renders to a view which is already figured out for us. We shouldn't have to go copy-paste a template.

  • Anonymous
    November 14, 2007
    Don't you need to html encode your description in the feed? Or are you assuming it's already encoded from the database? What about using an ASHX page instead? Regards Lee

  • Anonymous
    November 14, 2007
    ASP.NET: MVC Framework... e le mie perplessit

  • Anonymous
    November 14, 2007
    Brad, Thanks for the post. May i ask you a simple question which has puzzled me and so many around for long. What is the difference between 3-tier and MVC? If we are ok working with 3-tier architecture, why bother using MVC and vice versa. When should we use either one of these? Regards...

  • Anonymous
    November 14, 2007
    Looks good! Don't forget response encoding...perhaps as a PreFilterAttribute?

  • Anonymous
    November 15, 2007
    This looks good. A lot cleaner syntax then having to roll your own. One question I have (and this is the first I;ve seen anything in detail about your MVC framework so I appologive if it is covered elsewhere) is what if the controller wants to change additional properties or behavior of the view. So in your example what if we wanted the description of the feed to be set to indicate this the Top 10 feed etc.

  • Anonymous
    November 15, 2007
    Enough with the teasers guys ;) Looks awesome, just give it to us and give it now!!! This will run under VS 2005, correct?

  • Anonymous
    November 15, 2007
    You've been kicked (a good thing) - Trackback from DotNetKicks.com

  • Anonymous
    November 15, 2007
    correct me if I'm wrong since I'm new in this pattern: MVC is only used in presentation layer if I have the traditional 3 layers architecture (DAL, BLL, Presentation layer)? which actually means separating the most of code behind stuffs away from the actual aspx page.

  • Anonymous
    November 15, 2007
    I was wondering about this: using a handler (.ashx file) you don't have the overhead of the regular Page. Now since this is actually a ViewPage it has less overhead? Also, could you extend the example and make it so that the action on the controller can render either a regular HTML view or an RSS view, based on some kind of filter or parameter? Thanks!

  • Anonymous
    November 15, 2007
    On the right track - looks like it!   One question though - parameters.  Instead of specifying: http://localhost:64701/feed/FromPublisher?Publisher=WildAmerica Can we pass the param via: http://localhost:64701/feed/FromPublisher/WildAmerica There would be many benefits to the second syntax, or even the ability to specify one or the other (or accept both)

  • Anonymous
    November 15, 2007
    I don't like the fact that this way we end up with a lot of code in the mark-up of the page, instead of using webcontrols that hide the coding to the html designer. Apart from that, everything else is great

  • Anonymous
    November 15, 2007
    You might also want to set the mimetype. And also the urls you're giving are localhost ones with a port number that will vary.

  • Anonymous
    November 15, 2007
    Hi, can microsoft's mvc framework run on vs2005/.netframework 2.0 without any iis (mapping) setting ??

  • Anonymous
    November 15, 2007
    Philip, yes, you can make the URL’s more pretty…

  • Yes, ScottGu did a nice job of covering the URL format in his post… URL Format Behavior URL Example /Products/Categories Browse all Product Categories /Products/Categories /Products/List/Category List Products within a Category /Products/List/Beverages /Products/Detail/ProductID Show Details about a Specific Product /Products/Detail/34 Mike, You are right, an ashx page may have been a bit more lightweight..  but without any controls that do post-packviewstate this page is pretty tight… thought I have not measured anything yet. Oh, sure.. it would be very easy to add an HTML view… Wahyu, They way I think about it is that the ASP.NET MVC support is really about the UI part of your application.. you still likely need a N-tier architecture, this pattern helps you with the presentation tier…   Tom, Believe me we are working on it… Honestly, I ran into a few bugs that building this (that I will not mention here) so we are still a bit raw… but the team is working super hard to get this out in customer hands ASAP… we are talking about bring in a turkey next week to help keep folks focused ;-) Our plans are to support this on top of .NET Framework 3.5,and the tooling work will likely go into an update to VS2008…   Josh Berke. Good call Josh, in fact I ran into this and breezed over it for simplicity… the purest way to send more data to the view would be the extend the model… DotNetGuru, Yes, I think it is good to keep in mind that we are really only thinking about the ASP.NET MVC support as being about the UI tier of your application.. you still likely need a N-tier model in addition to this. snprbob86. Hey, I like the RenderFeed suggestion…   something tells me there will be a rich community of extensions such as these… Damien Guard, Doh!  You are right… I do need to HtmlEncode the output…  I control all the data (in and out) of the database, but you are right.. I should do this anyway. SixYo, This will work with IIS6 with no specific changes and .NET Framework 3.5VS 2008.
  • Anonymous
    November 15, 2007
    Isn't there already RSS/Atom generators in System.ComponentModel.Syndication?  There hasn't been too much blogged about it, but it appears to generate syntactically correct feeds for you complete with extensions.

  • Anonymous
    November 16, 2007
    Hi, I am interested in MVC because I am trying to write a templating system which will allow my users to write skins for my app. Ideally they would be able to structure their templates like this - http://www.liquidmarkup.org/ and then just upload them to my database. The app would then load the correct template in from the database when the page is produced. The one thing that worries me is that using the asp.net MVC approach my users would have to write aspx pages as their templates and would have to understand code behind too. Is there a simpler way of writing views ? Jon

  • Anonymous
    November 16, 2007
    Hi Brad, I don't think it's very wise of you to call Ray Ozzie a turkey. ;-)

  • Anonymous
    November 17, 2007
    Hi Brad; This example brings an interesting thought to my mind and see what you think: With MVC, can we develop systems that really does not generate any visual (HTML) UI to send back, but acts more like a WebService to generate a complete set of data to the requester?  i.e. A silverlight app can call a URL and receive data? But Can that SL app also send data to this type application to store in database? Thanks! ..Ben

  • Anonymous
    November 17, 2007
    Suggestion Brad; If you're planning to actively become involve with MVC and write and answer blogs, could you please quote a question (like Scott does) before answering? Perhaps the person who asked the question would understand your response, but if I didn't read his original question, your answer would not make any sense to me, as another reader, and I'm sure you're answering to educate the mass public and not only a few. Thanks! ..Ben

  • Anonymous
    November 18, 2007
    @Ben: the HTML would be one possible instance of the V in MVC. You aren't obligated to add an HTML view. Silverlight would just be your view in the example you use.

  • Anonymous
    November 18, 2007
    Would you please also post your unit test code for this sample?

  • Anonymous
    November 18, 2007
    Am I the only one that sees this: [ControllerAction] public void Top10(){...} [ControllerAction] public void FromMSFT(){...} and goes:waaaah? Even for a sample these are too specific in regards to OO aren't they? This could be because of the controllers and the url but that should be handled in the routing, it could be for the encaptulation of the linq code but still, wouldn't you separate that in to a different class? I'm by no means a purist, so am I missing something?

  • Anonymous
    November 18, 2007
    So if using MVC with an existing 3 tier architecture (web application project) you'd possibly end up with:

  1. DAL
  2. BLL
  3. Presentation layer - within which you've got a models, views and presenters sub directory structure? Is this a likely scenario?
  • Anonymous
    November 19, 2007
    In my always continuing efforts to keep up with the coolest frameworks, architecture, and other tidbits,...

  • Anonymous
    November 19, 2007
    >Scaryjones - >So if using MVC with an existing 3 tier architecture >(web application project) you'd possibly end up with: > >1) DAL > >2) BLL > >3) Presentation layer - within which you've got a >models, views and presenters sub directory >structure? Yes -- that is the sort of thing... I don't think that MVC would span your data layer (1) or your business objects (2)...  I agree that is need for workflow and testablity between them, but the asp.net MVC framework focuses on the presenation tier... Is this a likely scenario?

  • Anonymous
    November 20, 2007
    It's great to see some good examples of this stuff.  But, already off the bat, I see diverging patterns which is a bit of a concern.  I know they're early examples, but ScottGu says: "these helper methods will make it easy for us to cleanly retrieve the data model objects needed from our ProductsController class (without having to write the LINQ expressions within the Controller class itself):" while you write linq expressions directly in the controller.  I'm not opposed to either way, Rails writes activerecord queries in the controller and it works for them.  But, usually MS does a good job of being consistent in presenting good patterns. Also, writing xml tags by hand is a bit scary.  Why not use RSS.NET or something to generate the xml?  Once missing quote and angle bracket and nobody can read your feed.

  • Anonymous
    November 20, 2007
    Hi guys - more on the 3tier + MVC with reagrds to your example above... What about creating a new class library project and putting the VideoDatabase.dbml into that and any controllers in there. this would, in effect, be your Model and Controller. You can then use partial classes to extend the dbml class with helper linq funtions and then other classes which would be the your controller logic or just business logic. Then u have the MVC asp.net project for presentation layer, with a reference to the above class library. Finally you would have a Test Project for unit tests. How does that sound?

  • Anonymous
    November 26, 2007
    I could really do with seeing an example of how MVC replaces an postback 'update' on a form i.e. updating a row in a database.   Every example I've seen so far is a simple display of information.  Any chance of something a bit more in-depth?

  • Anonymous
    November 28, 2007
    I have already used MVC in mobile development. It is brilliant architecture. Please have a look in MCSF pattern  &practice. I did research the web client pattern&practice (WCSF). I think it uses the MVC as well. It seperates the UI, DAL and BLL. Has anyone compared the WCSF and the new ASP.NET MVC framework? If ASP.NET MVC framework = Ruby Rails...It gonna be great.

  • Anonymous
    November 30, 2007
    Jati - I've been playing around with the WCSF on a current project I'm doing 'for fun'. The WCSF is indeed an imlementation of MVC, but a rather unique one. Views are pages and aren't really meant to be re-used which does sort of go against the MVC pattern a little. If you grab the latest vNext release and not the main release, you'll see a bunch of changes to the WCSF including the addition of 'webparts' to the views which are meant to be the small reusable chunks of presentation code. The Asp.NET MVC framework looks altogether a little more elegant of a solution (with no offense meant to the hard work of the WCSF team) and the URL mapping is one of those wonderful features that shows a glimpse of genius. Can't wait to get my hands on it and re-work the WCSF to use it.

  • Anonymous
    December 03, 2007
    I just can't ignore how out of place the { and } are in the markup/view, with the foreach loop. I hope you can introduce something that can help developers avoid the use of such symbols in their view templates. Maybe something like what PHP has... foreach coupled with an endforeach?

  • Anonymous
    December 04, 2007
    Andre, <quote> I just can't ignore how out of place the { and } are in the markup/view, with the foreach loop. I hope you can introduce something that can help developers avoid the use of such symbols in their view templates. Maybe something like what PHP has... foreach coupled with an endforeach? </quote> If this is something that bothers you, I'd have thought you could use VB.NET instead of C# so the syntax becomes ForEach ... Next. I think ASP.NET MVC is definitely a step in the right direction.  I'd like to have an option of the view being even more separated from the code, so you can produce templates similar to those of the smarty template engine for PHP.  Perhaps you can using the declarative controls and databinding? Given the amount of logic in the routing engine, I'm also wondering about performance.  Are there any benchmarks available?

  • Anonymous
    December 09, 2007
    Ok, ok, it took us a little longer than we expected, but we finally got the ASP.NET 3.5 Extension Preview

  • Anonymous
    December 09, 2007
    Ok, ok, it took us a little longer than we expected, but we finally got the ASP.NET 3.5 Extension Preview

  • Anonymous
    December 09, 2007
    As I am sure you saw, we recently posted the ASP.NET 3.5 Extensions ... I thought i'd do a brief introduction

  • Anonymous
    December 09, 2007
    As I am sure you saw, we recently posted the ASP.NET 3.5 Extensions ... I thought i&#39;d do a brief

  • Anonymous
    December 10, 2007
    This week the first preview of the ASP.NET MVC framework was released to the web as part of the ASP.NET

  • Anonymous
    December 18, 2007
    As I am sure you saw, we recently posted the ASP.NET 3.5 Extensions ... I thought i&#39;d do a brief

  • Anonymous
    February 18, 2008
    Microsoft will release it's Model view controller base framework for asp.net. In this user will have

  • Anonymous
    February 18, 2008

  • Anonymous
    February 25, 2008
    Thanks to everybody who came out to the Ft. Lauderdale Architecture/Agile group meeting last Tuesday

  • Anonymous
    February 27, 2008
    Nov 17th Links: ASP.NET, ASP.NET AJAX, ASP.NET MVC, VS 2008, .NET 3.5, IIS7, Silverlight

  • Anonymous
    April 24, 2008
    Craig Shoemaker takes you on a tour of the best ASP.NET MVC resources available today. Listen to the

  • Anonymous
    February 11, 2009
    Petits cachotiers que nous sommes avec Pierre, nous vous avons gardé quelques petites surprises sur le

  • Anonymous
    June 06, 2009
    Thank you for submitting this cool story - Trackback from progg.ru