tags:

views:

404

answers:

6

It seems that my understanding of the use of partial views is not quite right.

I am trying to add a partial view which builds from a database and use the partial view within a master page.

Using the NerdDinner project (wich is great for mvc) I have added the following:

Views\Shared\dinners.ascx" :

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<NerdDinner.Models.Dinner>>" %>
<ul>
    <% foreach (var dinner in Model) { %>
        <li>
            <a href="/Dinners/Details/<%=dinner.DinnerID %>"><%= Html.Encode(dinner.Title) %></a> 
        </li>
<% } %>
</ul>

Within "Views\Shared\Site.Master" :

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
...
<% Html.RenderPartial("dinners"); %>

The above will only currently function on the pages where the dinners object is currently availabe as a list (eg site/Dinners). Is there a way to do this in an elegant and mvc way or is this something that requires a clever compromise?

+2  A: 

Why do you have it in your master? I would add another place holder to your master and then add it where it makes sense. I feel that master pages should be as agnostic to specifics. If you want it be on all dinner pages, just make nested master of the original one.

Daniel A. White
Appologies to ask a question that has discussed before, I am struggling to find an answer.The solution I am looking for does not have to reside in master; howeer adding a ViewData to every controller action doesnt seem elegant. Maybe Im missing something here.On a seperate but related note, is AJAX the neatest way to implment a CRUD based on partial views?
Desiny
I think you can nest master pages.
Daniel A. White
+2  A: 

This is, IMO, one of the biggest limitations of ASP.NET MVC - managing shared data across multiple views (next to rendering partial ascx views to strings!). If you google or search on stackoverflow for something like 'managing shared view data asp.net mvc' you'll get a ton of results with various options, none of which are really perfect. The MVC team at Microsoft have acknowledged this as a problem and will hopefully include a standard solution in a future release.

Depending on how you manage data access, the easiest way may be to create a base Controller class and retrieve the data you need for the partial either inside the constructor or inside OnActionExecuting().

The option that I have chosen is to use the Html.RenderAction() helper method inside the MvcContrib project. It basically enables you to call an action method from your view and render the response. This isn't great because it requires your view to have yet more knowledge about controllers, but it gives an easy short-term solution that doesn't require hooking up any extra code on your part.

roryf
A: 

partialview seems to me to be inherently flawed. It creates module coupling and breaks cohesion intentionally by definition.

le dorfier
A: 

I agree with Daniel, even if your control does not shows on every page, it shows on some of them, you should create your master as template only

Marko
+1  A: 

One method I use is to create a helper method and use it in your Master Page.

public static void RenderDinners(this HtmlHelper helper)
{
    helper.RenderAction<DinnersController>(c => c.Dinners());
}
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
...
<% Html.RenderDinners(); %>

As you can see the helper calls the Dinners Action method on the DinnersController.

public ActionResult Dinners()
{
   ...get dinners and put in the View
   return Dinners(view);
}
David Liddle
+2  A: 

This tutorial on stephan Walther's site deal with this issue. If you use an abstract base class where the dinners object is populated and inherit from that, it will always be available, but you'll have to be aware that it's there always even when you don't need it ;).

Morph