views:

1615

answers:

4

I've just finished my first ASP.NET MVC (2) CMS. Next step is to build website that will show data from CMS's database. This is website design:

http://img56.imageshack.us/img56/4676/portal.gif


#1 (Red box) - displays article categories. ViewModel:

public class CategoriesDisplay
    {
        public CategoriesDisplay() { }

        public int CategoryID { set; get; }
        public string CategoryTitle { set; get; }
    }

#2 (Brown box) - displays last x articles; skips those from green box #3. Viewmodel:

public class ArticleDisplay
    {
        public ArticleDisplay() { }

        public int CategoryID { set; get; }
        public string CategoryTitle { set; get; }

        public int ArticleID { set; get; }

        public string ArticleTitle { set; get; }
        public string URLArticleTitle { set; get; }
        public DateTime ArticleDate;

        public string ArticleContent { set; get; }

    }

#3 (green box) - Displays last x articles. Uses the same ViewModel as brown box #2

#4 (blue box) - Displays list of upcoming events. Uses dataContext.Model.Event as ViewModel

Boxes #1, #2 and #4 will repeat all over the site and they are part of Master Page. So, my question is: what is the best way to transfer this data from Model to Controller and finally to View pages?

  1. Should I make a controller for master page and ViewModel class that will wrap all this classes together OR
  2. Should I create partial Views for every of these boxes and make each of them inherit appropriate class (if it is even possible that it works this way?) OR
  3. Should I put this repeated code in all controllers and all additional data transfer via ViewData, which would be probably the worse way :) OR
  4. There is maybe a better and more simple way but I don't know/see it?


Thanks in advance, Ile



EDIT:
If your answer is #1, then please explain how to make a controller for master page!

EDIT 2:
In this tutorial is described how to pass data to master page using abstract class: http://www.asp.net/LEARN/mvc/tutorial-13-cs.aspx
In "Listing 5 – Controllers\MoviesController.cs", data is retrieved directly from database using LINQ, not from repository. So, I wonder if this is just in this tutorial, or there is some trick here and repository can't/shouldn't be used?

+2  A: 

I fought with this as well. Initially I did a lot of dumping of extra data into the ViewData, which ended up having to be casted back (made some extensions that eased this, but still not great).

I would go with your choice #1 and make a ViewModel that wraps all of the classes you would need.

hunter
I edit my question... I forgot to add that I have no idea how to make controller for master page (I'm asp.net newbie)
ile
A: 

The answer is here:
http://www.asp.net/LEARN/mvc/tutorial-13-cs.aspx

ile
This uses a non strongly typed dictionary ("Magic Strings"). Which the compiler will not pickup typos for and does not support quick/easy re-factoring.
mxmissile
+3  A: 

To get data to my Master Page:

  • I don't like using an abstract class to get data to the master page. I prefer composition over inheritance.
  • I don't like to use the ViewData dictionary because it's not strongly typed.

I would create Views, ViewModels and Actions for each section. Then call Html.RenderAction(...) For example:

I would create CategoriesDisplay.aspx with only the html for the redbox. I would pass that your CategoriesDisplay model. Then in my controller:

public class CategoryController : Controller
{
    public ActionResult DisplayCategories()
    {
      var model = new CategoriesDisplay();
      ...
      return View(model);
    }
}

Then in my Master Page:

<% Html.RenderAction<CategoryController>(c => c.DisplayCategoreis()); %>

This will render the CategoriesDisplay view inline within the Master Page. Which in turn allows you have SOC (Seperation of Concerns), clean and manageable code.

mxmissile
I probably should add, the Html.RenderAction extension I used is part of the Asp.Net MVC futures assembly. http://aspnet.codeplex.com/releases/view/41742
mxmissile
I see... didn't know what was this Html.RenderAction so I was a bit sceptic. This definitely sounds like more interesting solution than the one with abstract class. I will try it in a day or two and see if it really all works to me :) Thanks maxmissile!
ile
Is it possible to make one controller action and us it in different views? To be more precise, is it possible to define inside Html.RenderAction() wich Controller, which Action and which View to use?
ile
Yes RenderAction can be called from any view and pointed to any Controller.
mxmissile
A: 

I agree with mxmissile, Html.RenderAction() is the best way to go. It keeps your models and your views clean and simple. Also, ASP.Net 2 supports it out of the box so no need for MVC futures.

Ours