Gavin
Gavin

Reputation: 1233

asp.net mvc partialview

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?

Upvotes: 0

Views: 621

Answers (6)

Morph
Morph

Reputation: 1719

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 ;).

Upvotes: 2

David
David

Reputation: 15360

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);
}

Upvotes: 1

Marko
Marko

Reputation: 1924

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

Upvotes: 0

dkretz
dkretz

Reputation: 37655

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

Upvotes: 0

roryf
roryf

Reputation: 30170

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.

Upvotes: 2

Daniel A. White
Daniel A. White

Reputation: 191056

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.

Upvotes: 2

Related Questions