Learn More





DNN Community Blog

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

Learning Razor 1 - RSS-App Part 1: Overview and Basic Script

Since it's now time to get our hands dirty, let me show you how to create a Razor based App. In this first post I'll show you what we'll do in what steps, and we'll create the first version which will already work.

Why start with an RSS-Feed?

Razor is specialized in output - so my first App must be something that has very little data-storage, to keep things simple. You'll see that even this App will need data storage - so we'll get to that - but the first iteration will need zero storage and allow us to use the default DNN Razor Host.

There's another reason: most classic Feed-Apps are XSLT-based. This is a powerful technology which almost nobody masters - so when this App is done, it will be very easy for everybody to customize to their needed look & feel - and probably replacing the other open sources feed modules.

The Phases we'll go through

  1. Create a very basic script that retrieves the RSS-Feed and loops through the items to show in a table
    This is the very basic scenario, without bells and whistles and to change the feed-url would require the user to modify the CSHTML. So it doesn't scale well, but it has very little code and will be easy to start with.
  2. Make it more generic: Package as an App, allow end-user Configuration
    Here we'll move from the Razor-Host to a 2sxc-App, so that the web site owner (who can't program) can configure things like the Feed-URL and the amount of items to show.
  3. Add Image-Integration and a Lightbox
    Many feeds will also offer an image - but there are different standards. We'll add some helpers to make this happen, and learn about @functions.
  4. Implement support for DNN-Search, so that all items will also be found in the DNN-Search
    We don't want the feed to just be displayed to the user - we also want the DNN-Search engine (since 7.2) to pick up our content so that it's feature in search results. This is very easy to do - we'll just do a minimal implementation ensuring that all the feed-items we're currently showing also feature inside the search results.
    We'll also learn a bit of LINQ on the way…
  5. Create multiple outputs (tables, list, etc.)
    In the third lesson, we'll enable view-customization (by offering settings like "show/hide image" and create various different outputs for the same feed - because you'll want to offer multiple views. We'll also outsource the feed-retrieval code away from our output template to ensure re-usability and Separation of Concerns (SoC).
  6. Make it Multi-Lingual
    Here we'll make the data multi-language compatible (so each language can have a different feed) and we'll also make the Razor-Scripts multi-language compatible by adding centralized resources.
  7. Add some power features
    Here we'll improve the system a bit to enable feed-mixing (when you want to retrieve multiple feeds and mix them) and maybe other things - place your wishes at the end of the posts so I can integrate it into this last post!

Phase 1: Basic script that retrieves an RSS-Feed and shows it


  1. Write a CSHTML Razor Script (C# Razor)
  2. Use the feed for this Blog
  3. Retrieve it
  4. Show it so it will look as follows
  5. …and add instructions, so you can do the same

Step 1: Add a Razor-Host module to a new page with a blank script

This is rather trivial, but in case you don't know how, I've created a short video to keep things simple - watch here:

Step 2: Create a draft HTML-Table

Razor is all about HTML + some placeholders. So we'll start with the HTML. This is the HTML before Razor hits it:

Step 3: Get data

Now we will retrieve the RSS-Data. Here's what the code will do

  1. It's inline and above the HTML - so it will be parsed before the HTML. This is very different from WebForms, which doesn't have a top-down pattern. This also makes it much easier to understand simple scripts.
  2. It will simply create a variable that's available on the whole page…
  3. Which will be an XDocument object (an XML-Document that understands LINQ, but not to be confused with the XmlDocument which doesn't understand LINQ)

    Here the same code with some annotations

    Step 3: Combine

    The code below is now the combination of the two sets. Because the XDocument is XML based, we also have to use commands like feed.Element("title").Value to retrieve a value. Not very sexy, but functional for now. We'll make this all much nicer in one of the following lessons.

     Again - with some annotations...

    The Result

    Let's look at the resulting output - you can find it here:

    You can also download the piece this piece of code (just the CSHTML-Razor) from the forge or directly from CodePlex.

    Wrapping up Phase 1 - Good and Bad

    The current solution is quickly implemented and works. You could now go ahead and modify the HTML to suit your website, and you could get most of it to work very well. But it's not very sexy. Here are some drawbacks to the current solution:

    1. It needs a programmer to change the feed-url because it's stored in the CSHTML…
    2. …and because it's Razor, you also need Host-permissions. Not sexy :(
    3. The script lies in /DesktopModules/ - so it's shared across portals. This isn't nice for security reasons, and also not because you might want different looks on each portal.
    4. You can't really package your work and re-distribute it.
    5. You can't have instance-based settings. So every time you had a feed, you would need to create a new script - which you would have to maintain in the future.
    6. It's not multi-language capable - so if you needed a different feed in another language, again you would have to create a new script
    7. It doesn't show feed images 
    8. It's not integrated in the DNN-Search yet
    9. The admin can't control the presentation (like decide to show/hide images or reduce the amount of items)
    10. The admin couldn't easily switch to another view like a 2-column look instead of a table

    All these shortcomings will be handled in the following lessons :). Stay tuned!

With love from Switzerland

Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 600 DNN projects since 1999. He is also chief architect of 2sxc (2SexyContent - see forge), an open source module for creating attractive content and DNN Apps.


2sic Daniel Mettler
Nokiko ( sent me this in an e-mail which I would like to share:

nice article
here is how I did mine used xpath isntead of linq

@using ToSic.Eav.DataSources
@using System.Xml.XPath;
@using System.Xml;

bool isValid;

//Fetch RSS XML

var rssurl = ""
XmlTextReader dnnRSS = new XmlTextReader(rssurl);

//Create new XML document
XmlDocument doc = new XmlDocument();

//Load in our remote XML into our XML document

//Select our nodes we want with some xPath
XmlNodeList rssItems = doc.SelectNodes("//item");
isValid = true;

    //For each item node we can then ouput what we want
    foreach (XmlNode node in rssItems)

  • @node["pubDate"].InnerText


  • }

catch (XmlException e)
isValid = false;


@if (isValid == false) {

2sic Daniel Mettler Monday, September 08, 2014 2:23 AM (link)
Geoff Barlow
Hi Daniel,

Great blog!

I have used the razor module a couple of times now, mainly for sub navigation but with module dev I'm looking for a good way to do templating and I think this is the way I should be looking at doing this.

Also maybe you should contact Will Strohl and get these blog posts into a tutorial for other users.

As you probably know Will is heading the 'training working group' and I think this will be a great addition.

Looking forward to your next blog,


Geoff Barlow Monday, September 08, 2014 5:46 AM (link)

Comment Form

Only registered users may post comments.


2sic Daniel Mettler (124)
Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (22)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (203)
Chris Paterra (55)
Clinton Patterson (28)
Cuong Dang (21)
Daniel Bartholomew (2)
Dave Buckner (2)
David Poindexter (3)
David Rodriguez (2)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (6)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (270)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (52)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (37)
Will Strohl (163)
William Severance (5)
Try Evoq
For Free
Start Free Trial
a Demo
See Evoq Live
Need More Information?