开发者

How to check if a variable is defined in a Master file in ASP.NET MVC

I've got a Site.Master file I've created to be my template for the majority of the site, with a navigation. This navigation is dynamically created, based on a recursive Entity (called Page) - Pages with a parentID of 0 are top level, and naturally each child carries it's parent's Id in that field.

I've created a quick little HTML Helper that accepts the ID of an Page and generates the nav by doing a foreach on the children that have a parentId matching the passed Id. On the majority of the site, I want the Site.Master to use a parentId of 0, but if I'm on a strongly typed View displaying a Page, I naturally want to use the Id of the page.

Is there a way to do such conditional lo开发者_运维知识库gic in a Site.Master (and, does that violate MVC rules)? "If I'm on a strongly typed Page of /Page/{Id}, use the Id render nav, else use 0"


It sounds like your PageID is only useful in the Pages Controller.

Consider passing the PageID via the ViewData into your View. The Master Page can simply check whether the ViewData exists, and optionally call your Html helper method.

Pages Controller:

    ViewData["PageID"] = somePageID; //zero or non-zero.

Master: when any controller infact passes a value in ViewData for PageID, the Html snippet will be written. When it's not passed, it's an inexpensive check for null.

<% if (ViewData["PageID"] != null)
{
   Response.Write(Html.RenderNav(ViewData["PageID"]));
}
%>

This style, to me, makes the most sense. The PagesController passes a simple value into the ViewData.

Contrast this with the Master Page trying determine, on every request,: what's the URL is, who's the Controller, OK, now go get the PageID, is it numeric, ok, now write the HTML. All that logic doesn't belong in the View. As the convention goes: keep Views dumb.

Prefer to keep this out of your strongly typed ViewModels, but rather use in ViewData. This way, it's a simple check for existance in the Master, which is NOT strongly typed.

I'll suggest that the ViewData strategy is easier to understand and maintain.

It sounds that you're wanting to write out this Navigation in the Master. Perhaps consider moving it to a Content Area, where the View has the fine-grain control of what appears?

Pages View:

<asp:Content ID="nav" ContentPlaceHolderID="PagesNavContent" runat="server">
    <%= Html.RenderNav(ViewData["PageID"])%>
</asp:Content>


Figured it out:

        int navPageId = 0;
        if (ViewContext.RouteData.Values["controller"] == "Pages" && ViewContext.RouteData.Values["Id"] != null)
        {
            navPageId = Convert.ToInt32(ViewContext.RouteData.Values["Id"]);
        }
        Html.RenderNav(navPageId);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜