Getting started with ASP.NET MVC3 and Tridion

Introduction

In this post I am going to explain how to set up and use the Dynamic Delivery For Tridion Framework. If you haven’t heared of this framework check out this site: http://code.google.com/p/dynamic-delivery-4-tridion/
In short: Dynamic Delivery For Tridion (DD4T) is an ASP.NET MVC3 framework specifically designed to build a web(site) application using SDL Tridion.

Prerequisites:
1. Visual Studio 2010 (With Entity Framework 4.1 installed and MVC3)
2. SDL Tridion 2011 Content Management Server
3. SDL Tridion 2011 Content Delivery Instance
(The DD4T Framework also supports SDL Tridion 2009. But in this post I use SDL Tridion 2011)

Also make sure that you are publishing everything to the Tridion Broker Database. (You can configure this in the cd_storage_conf.xml)

High level overview

For a highlevel overview of the framework, check out this url: http://prezi.com/tzxk2w9ic284/developing-with-aspnet-mvc-and-tridion/

To get your website up and running using the DD4T framework, the following steps are needed:

  1. Upload the Dynamic Delivery Template Building Blocks to your Content Management Server
  2. Create Component Templates and Page Templates using the Dynamic Delivery Template Building Blocks
  3. Create a webapplication that uses the DD4T DLL’s to show your published page

Getting started

Download the sources from code.google.com
(Use a SVN Client like TortoiseSvn in combination with a Visual Studio plugin like AnkhSvn)

The sources contain the Java version and the .NET MVC3 version of the project. We are only interested in the .NET MVC3 version of the framework.

Template Building Blocks

First, we have to upload the Template Building Blocks to the Tridion Content Management Server.
Check out this WIKI page on how to upload the templates

Component Templates and Page Templates

Once you uploaded the Template Building Blocks, you can use these to create Page- and Component Templates. To create a Component Template, open up the Templatebuilder tool and create a new Component Template. Drag and drop the following (DD4T) Building Blocks on your template:

  • Generate dynamic component
  • Publish binaries for component

Also, create a Page Template with the following (DD4T) Building Blocks:

  • Generate dynamic page
  • Publish binaries for page

Next, create a simple meta-data schema with one single line text (Preferably it’s a selectlist with values from a category) for usage on the newly created Component- and Page Template.
This schema allows you to tell the DD4T framework which View (visual representation, ASP.NET MVC3 Razor template) to use when this Page/Component is rendered in the browser.
Xml name of the field should be ‘view’.

Component Template for Articles, using the View ‘Article’:

Do the same for the Page Template: Give it a metadata-schema, with one field called ‘view’ and insert which view to use in the framework:

Visual Studio Projects setup

Open up Visual Studio and create new project of type ‘ASP.NET MVC3 Web Application’ (Make sure you are using the Razor view engine)

Next, we are going to add some projects (dll’s) from the just downloaded DD4T framework. Choose from the ‘File’ menu for ‘Add’ -> ‘Existing Project’. Add the following DD4T projects to your solution:

  • DD4T.ContentModel
  • DD4T.ContentModel.Contracts
  • DD4T.Factories
  • DD4T.Mvc
  • DD4T.Providers.SDLTridion2011 (Or DD4T.Providers.SDLTridion2009 if you are using SDL Tridion 2009)

Your solution looks something like this:

Remark: in a real life application you don’t want hard references to all these dlls. You want to load the dependencies by means of Dependency Injection (Unity, MEF, etc)
Next, we have to copy some Tridion dll’s into the following folder: %DD4T Install Path%\dependencies\Tridion 2011 DLLs. In here you find a file called ‘Missing files’. Read it, and copy-paste all the Tridion Dll’s into this folder.
Now, add all the DD4T projects as a reference to your MvcApplication. Your solution should build fine now.

The DD4T framework uses the web.config to find out from which publication to request content. Add the following 2 keys to the web.config. (Of course, fill in your publication id)

<add key="Site.ActiveWebsite" value="Corporate.En"/>
<add key="WebSite.Corporate.En.PublicationId" value="7"/>

Writing *some* code

Now we have added all the necessary framework parts, it’s time to wire up our first controller so we can view our page in the browser. Luckily for us, the DD4T framework has already done a lot for us. Al we have to do is to use the right methods and classes!
If you aren’t familiar with the .NET MVC pattern, this is roughly how it looks like:

  1. Url is typed into the browser
  2. Request is fired to the webserver and our webapplication. It goes through a ‘rout-engine’ (Global.asax) to find out what to do with this url (request)
  3. This route-engine looks at the url and based on the parts of the url it sends it to a controller
  4. The controller builds up the Model and passes this model on to the View
  5. The (razor)View renders the HTML and pushes the output back to the browser

First step is adding a rule to the Global.asax that makes sure that (for now) all requests are handled by the same controller. Add the following code to the ‘RegisterRoutes’ method from the Global.asax:

routes.MapRoute(
               "TridionPage", // Route name
               "{*PageId}",
               new { controller = "TridionPage", action = "Page" }, //Parameter defaults
               new { pageId = @"^(.*)?$" } //Parameter constraints
           );

This makes sure that every request is passed on to the TridionPageController.

Time to make the TridionPageController! Go to your MvcApplication and create a new controller. Right click on the ‘Controller’ folder in the solution explorer and choose ‘Add’-> ‘Controller’.
Name it: TridionPageController

By default all controllers from ASP.NET MVC inherit from the Microsoft Controller class. We don’t want this. We want to inherit from the TridionControllerBase class from the DD4T.Mvc project.
Make sure your TridionPageController inherits from the TridionControllerBase:

public class TridionPageController : TridionControllerBase
{
        public TridionPageController()
        {
            this.PageFactory = new DD4T.Factories.PageFactory();
            this.PageFactory.PageProvider = new DD4T.Providers.SDLTridion2011.TridionPageProvider();
        }
}

Remark about the above code: The factories and providers are created here for simplicity. In a real world scenario you don’t want to do this, but you want to load the Factories and Providers by means of Dependency Injection (Unity, MEF, etc). But for now it’s ok.

The TridionControllerBase defines a set of useful methods. We want our controller to look up the page (url) we requested in the browser from the Tridion Broker Database. Normally you would write code, using the Tridion dll’s to retrieve the Pagecontent from the Tridion Broker Database yourself, but the DD4T framework has already done this for us.

Add the following code to the TridionPageController:

public override ActionResult Page(string pageId)
{
    return base.Page(pageId);
}

This method retrieves the PageContent from the Tridion Broker Database by finding the Page by it’s Url (pageId = Url). So, make sure you published a page to the Tridion Broker Database using the DD4T Templates!

The View

The ‘Page’ method returns *something*, but we have to define of course how that ‘something’ needs to be visualed. In other words: we need to create a (razor) view.
ASP.NET MVC3 uses a pattern to find the right View to visualize this page and it uses (among others) the name of the Controller to find the view. So, in the ‘Views’ folder, create a new folder
‘TridionPage’. In here we have to define the View. Remeber the metadata schema we made for Component- and Page Templates? Well, your Pagetemplate has this metadata on it, and you gave it a meaningfull name. I named mine ‘General’. So I have to create a view named ‘General’. Here is how my folder structure looks like:

Views contain the HTML. Here we define how our page looks like. One of the advantages of the DD4T Framwork is, that you can have strongly typed views. This means that you tell your View that he (she) needs to render HTML for object of type IPage or IComponent or String (not very usefull) or MyArticleObject, etc. This gives you full intellisense when writing your View.

Your view needs to render the HTML for an IPage object. (IPage object comes from the DD4T Framework).
Add the following code to your view:

@using DD4T.ContentModel;
@model IPage</pre>
<h2>@Model.Title</h2>
<pre>
    Some info about this page:

    Filename: @Model.Filename

    Title: @Model.Title

    Publication Title: @Model.Publication.Title

Component presentations on this page:</pre>
<ul>
<ul>@{</ul>
</ul>
&nbsp;
<ul>
<ul>foreach (IComponentPresentation cp in Model.ComponentPresentations)</ul>
</ul>
&nbsp;
<ul>
<ul>{</ul>
</ul>
&nbsp;
<ul>
<ul>
	<li>@cp.Component.Fields["title"].Value</li>
</ul>
</ul>
&nbsp;
<ul>
<ul>}</ul>
</ul>
&nbsp;
<ul>}</ul>
<pre>

ASP.NET automatically wires up the properties from the IPage to the ‘Model’ keyword because we told this View that he (she) is destined to render HTML for an IPage object. (The ‘@model IPage’ directive).

And now: RUN! (F5)
Make sure you are requesting an Url that is published to the Tridion Broker Database πŸ™‚

I hope this gives you enough information to get started with the DD4T Framework. The framework is actively developed and it is already running live in at least one big financial organisation.
So far everything runs just fine πŸ™‚

Disclaimer:This example is provided as is and is simplified for the obvious reasons.

Advertisements

21 Responses to Getting started with ASP.NET MVC3 and Tridion

  1. Andy Rowland says:

    Looks good. You list Tridion 2011 as a prerequisite. Does this mean that it cannot be used with 2009?

    • albertromkes says:

      Hi Andy,

      This post targets SDL Tridion 2011. But the DD4T Framework certainly works with SDL Tridion 2009. Just add the DD4T.Providers.SDLTridion2009 instead of the DD4T.Providers.SDLTridion2011 project and you are good to go.

  2. The link to the wiki page about the templates is wrong πŸ˜‰ It should be http://code.google.com/p/dynamic-delivery-4-tridion/wiki/40_Templates.

    Great stuff though Albert πŸ™‚

  3. Sachin says:

    Albert,

    This is a great post. I am however curious to understand how will this work with a “multi-channel” marketing theory. Are you proposing this framework for WEB only whereas the other channels still continue to use the traditional architecture of being driven by templates via Tridion?

    Basically, I am looking at reasons to embrace this model in a DMP world.

    • albertromkes says:

      Hi Sachin,

      I didn’t use this framework for other channels yet, but as far as I can see it’s perfectly possible to use DD4T for the mobile channel. (Integrating with netbiscuits). All you have to do is to make sure that your (mobile) views output BiscuitML.

  4. vensi says:

    Hi Ablert,

    Your post helps me lot. Thanks and keep going. I have one question, do we can develop the dynamic component presentation pages using DD4T?

    • albertromkes says:

      Hi,

      Yes. DD4T fits perfectly in a dynamic environment as you describe it. You can pull DCP’s (containing XML!) from the Tridion Broker Database and use it to construct your Model and View (HTML).

  5. vensi says:

    Hi Albert,

    I was following your post and tried creating a sample application in my local machine. Do we need to configure the Tridion config xml and jar file locally to run the application? I have not seen the steps in your post. Please advise me how to proceed. Currently i have created a page(using DD4T Templates) in Tridion and published it to Broker DB. I got the below error when I run the application locally.

    Server Error in ‘/’ Application.
    ——————————————————————————–

    The resource cannot be found.
    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

    Requested URL: /Views/TridionPage/General.cshtml

    • albertromkes says:

      Hi,

      You need a Tridion Content Delivery Instance. You can configure a TRIDION_HOME environment variable for this OR you can configure the Content Delivery instance ‘locally’ in your asp.net mvc3 application; just copy the appropriate dll’s and the (tridion) ‘lib’ and ‘config’ directory in your ‘bin’ directory. You can find the dll’s, bin and lib directory in the Tridion Content Delivery installer files. (You need the API server role). In the config dir you need at least the cd_dynamic_conf.xml and the cd_storage_conf.xml.
      If you have these files and dir’s in place, running the application (f5) will start the Tridion Content Delivery instance.

  6. vensi says:

    Hi,

    I have configured the way in which you have explained. I have also set in the project property file virtual path: /TridionPage/1659 where 1659 is the page id which is created in Tridion.

    I have created General.html page using DD4T PT in Tridion and published it to DB. When I execute the application it shows error in GetLastPublishedDateByUrl() in TridionPageProvider class.

    β€œAn attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)”
    The Publication id is null. Could you please let me know how we need to requesting an Url that is published to the Tridion Broker Database. Also it seems my publication id which I given in web.config file is not reading. Please let me know how to proceed.

    • albertromkes says:

      β€œAn attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)” usually means that you are mixing 32bits and 64bits dll’s. Play around with the Tridion dll’s in your bin directory and/or your Java version.

      The ‘value’ attribute from the setting ‘Site.ActiveWebsite’ corresponds with the ‘key’ attribute from the ‘WebSite.Corporate.En.PublicationId’ setting. If you change the first one, you also have to change the second one.
      Try setting the publicationId hardcoded:

      this.PageProvider.PublicationId = 7;

      • Vensi says:

        Hi Albert,

        Thanks for the reply. Now I am getting the below error in my log.

        ERROR Query – Unable to Configure for BrokerQuerying, query DAO could not be retrieved

        com.tridion.broker.StorageException: No Data Access Object for Query

        at com.tridion.storage.filesystem.FSDAOFactory.getDAOForTypeMapping(FSDAOFactory.java:174) ~[cd_datalayer.jar:na]

        at com.tridion.storage.StorageManagerFactory.getOriginalDAO(StorageManagerFactory.java:455) ~[cd_datalayer.jar:na]

        at com.tridion.storage.StorageManagerFactory.getDAO(StorageManagerFactory.java:301) ~[cd_datalayer.jar:na]

        at com.tridion.storage.StorageManagerFactory.getDefaultDAO(StorageManagerFactory.java:216) ~[cd_datalayer.jar:na]

        at com.tridion.broker.querying.Query.(Query.java:45) ~[cd_broker.jar:na]

        ERROR Query – Unable to execute Broker Query, no QueryGenerator was initialized

        Was the problem regarding to License or Any configuration setting that I have to do in the Content delivery side?

      • albertromkes says:

        Yes. This is a configuration issue with your Content Delivery Instance. DD4T works fine, but the Tridion Content Delivery instance cannot query the broker. Check your cd_storage_conf.xml to make sure everything is stored in the Tridion Broker Database. Also (double) check that all the .jar files are present in the ‘lib’ directory. Especially sqljdbc4.jar if you are using SQL Server 2008 for the Broker Database.

  7. Rash says:

    Hi Albert,

    This is a great post. I was following your post to set up DD4T framework. I am trying to set it up on 64 bit machine, and getting an error β€œAn attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)”. However, this thinhgs are working fine on 32-bit machine.

    I am having 64 bit machine running on 64-bit java and have also checked that all my dlls are targeting “Any CPU” framework. Can you suggest me something why its failing?

    • albertromkes says:

      Hi Rash,

      The Visual Studio webserver only supports 32 bits. If you want to develop against the 64 bits versions, you have to use IIS. Set up an website in IIS, point it to your sources and tell Visual Studio to use IIS as the webserver.

  8. Andy Rowland says:

    Hi Albert

    I’m attempting to create the templates as described in the WIKI. I’m using Tridion 2009.

    The problem I have is that the Dynamic Delivery Publishing solution does not compile, and therefore does not complete the post build event to upload the dlls.

    The DD4T.Templates, and DD4T.Templates.Base projects are missing references to the following assemblies:

    Tridion.ContentManager.Common
    Tridion.ContentManager,Templating.SiteEdit
    Tridion.Logging

    I’m building the solution on the Tridion 2009 server itself, and these assemblies do not appear to exist anywhere. Have these projects been coded with only 2011 in mind?

    Would you be able to provide some Tridion 2009 instructions?

    Take care

    Andy

  9. vensi says:

    Albert,

    Could you give an idea how we can render the navigation using DD4T. and what kind of changes we need to carryout both from Tridion side and MVC.

    Appreciate your help.

    • albertromkes says:

      Hi,

      Check out the TridionSiteMapProvider in the DD4T.Mvc project.
      It works just like the default ASP.NET sitemap. So it needs XML. This XML has to come from Tridion. There is no template (yet) in the framework that renders the XML for you, but if you search on the SDL Tridion forum you can find a complete method (TBB) that renders the (ASP.NET) sitemap XML based on your structuregroups in Tridion. Next, you have to register the TridionSiteMapProdiver in Web.Config from your webapplication. Also, add a key to the Web.Config (SitemapPath) that points to the url of your sitemap. (The XML for the sitemap should be stored in the Broker Database)

      This should get you started.

  10. Arjen Stobbe says:

    In my situation a Page is published to the Broker Database, but string[] resultUris = pageQuery.ExecuteQuery(); in TridionPageProvider.GetContentByUrl returns null. Also the following doesnt return anything:

    string pageContent = string.Empty;
    PageFactory.TryGetPageContent(“tcm:8-150-64”, out pageContent);

    Where should I start looking for a resolution? I dont see anything in any log file that could get me started.

    • albertromkes says:

      Hi Arjen,

      Logfiles to check are the default Tridion CD logs. Also the Windows Eventviewer might have some info, but don’t think it’s gonna be helpful in this case.
      If there is no exception thrown, I would (re)check the following:

      – Is the Tridion ContentDelivery instance configured correctly? (Pointing to the right Broker DB)
      – Is the content *really* in the DB. Check the Db directly.
      – Is this the right tcm-uri? Not a localized one? (Publication id)
      – Can you set a breakpoint in the code and follow the code? (I think you already did this. Check the publication id)

      Not really helpful, but hope this gives you something to go further with

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: