How can I set a variable on a _Layout page?

2020-06-09 08:01发布

I have a view and I want to use a layout page. In the layout page I want to have a conditional banner which some of the view will turn on/off. Just wondering how I can do this?

I have this in the _Layout.cshtml page...

@if (ShowBanner){

   <h1>banner</h1>

}

I'm wondering how I can turn this on/off from my MVC View page? Or whether this is the right thing to do at all? I mean if I declare that variable in the View page surely the master doesn't know about it? How do the two communicate through c#? Do I use the Viewbag? Rather not.

I know with forms its all about referencing the Page or Master member, just cant quite seem to see it with MVC...

Any help much appreciated...

Thanks Pete

3条回答
干净又极端
2楼-- · 2020-06-09 08:14

You can define a SECTION in your Layout, and then if your View is responsible to "fill" that section... your view can place the HTML in that section.

Here you can see a detailed step by step tutorial on using SECTIONS:

http://weblogs.asp.net/scottgu/archive/2010/12/30/asp-net-mvc-3-layouts-and-sections-with-razor.aspx

查看更多
在下西门庆
3楼-- · 2020-06-09 08:20

Having a model for your layout is not a good idea as it will force all views to use that model. However, you could put that type of information into the ViewBag and have the value populated in the constructor of one of your controller bases.

查看更多
走好不送
4楼-- · 2020-06-09 08:33

I'm with you, Exitos: I avoid using ViewBag too. Aside from the silly name, I dislike the weak typing that comes along with it. There is a solution, but it's kind of involved, so bear with me.

First, create a class to store the "display hints" that are to be passed to the layout. I creatively call this class "DisplayHints":

public class DisplayHints {
  // anything that you want passed from a view to the layout goes here
  public bool ShowBanner { get; set; }
}

Then, create a class deriving from WebViewPage<T> that will be the new base class of your views. Note how we have a property called DisplayHints that's stored in ViewData (which is available to the controller, the view, and the layout):

public abstract class MyViewPage<T> : WebViewPage<T> {
  public DisplayHints DisplayHints {
    get {
      if( !ViewData.ContainsKey("DisplayHints") )
        ViewData["DisplayHints"] = new DisplayHints();
      return (DisplayHints)ViewData["DisplayHints"];
    }
  }
}

As a commenter pointed out below, ViewData is weakly-typed, just like ViewBag. However, there's no way I know of to avoid storing something in ViewData/ViewBag; this just minimizes the number of weakly-typed variables to one. Once you've done this, you can store as much strongly-typed information in DisplayHints as you want.

Now that you have a base class for your views, in Web.config, we need to tell MVC to use your custom base class:

<pages pageBaseType="MyNamespace.Views.MyViewPage">

It sounds like a lot of trouble, but you gain some serious functionality for all this work. Now in your view, you can set any display hint you want as follows:

@{ DisplayHints.ShowBanner = true; }

And in your layout, you can access it just as easily:

@if( DisplayHints.ShowBanner ) {
  <div>My banner....</div>
}

I hope this helps!

查看更多
登录 后发表回答