49
votes

I'm using ASP.NET MVC 3 with Razor views. When you want to create a view you can choose a layout (master page) for your view, or leave it to choose Default (_Layout).

I am interesting in to change this layout after create a view without recreate it, is there any where to store the layout information about the views? and how can I change it?

4
What exactly do you mean by "without recreate it"? Recreate it how? change it how? Do you mean change the layout without reloading the page? You need to be more specific.Erik Funkenbusch

4 Answers

73
votes

In MVC3 you have _ViewStart.cshtml that stores all pages' Layout; you can change this element to change all pages' Layout or you can add new Layout element in top of target view pages in @{} block like the following to change the layout of the specific page:

@{
    Layout = "~/Views/Shared/_newLayout.cshtml";
    ViewBag.Title = "Index";
}
23
votes

After creating your view in the top of cshtml file you can see your layout included.

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

You can simply replace that for example with different layout

@{
    Layout = "~/Views/Shared/_Layout2.cshtml";
}

Also, you can store this in the base layout (_ViewStart.cshtml) and then all your views will use that layout.

22
votes

There are multiple ways to specify a different layout for a view, depending on your needs:

In the View

As mentioned in other answers, simply change the view's Layout property:

@{
    Layout = "~/Views/Shared/_CustomLayout.cshtml";
}

In _ViewStart.cshtml

MVC 3 added a default Views/_ViewStart.cshtml into which you can put logic which is shared by all views. You can also create additional _ViewStart.cshtml files in any Views subdirectory for additional custom logic (it will search up the hierarchy and in Shared folders, just like when finding any other view or partial).

Putting a lot of business logic into this feels like a violation of the "separation of concerns" principle, but at the same time it can be very handy.

Note that _ViewStart.cshtml inherits from StartPage, not WebPage, so its properties may be slightly different from what you're used to (e.g. you have to go through ViewContext to get the ViewBag).

@{
    if (ViewContext.ViewBag.IsAdmin) // or other custom logic
    {
        Layout = "~/Views/Shared/_AdminLayout.cshtml";
    }
    else
    {
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
}

In the Controller action

The View() method has an overload which takes an explicit layout page (Intellisense refers to it as a "master page"):

    public ActionResult FooAction()
    {
        var model = new MyModel();

        return View("Index", "_CustomLayout", model);
    }
7
votes

We can change the default rendering of layouts with in _ViewStart file by using the below code:

@{
 var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();

 string layout = "";
 if (controller == "Admin")
 {
 layout = "~/Views/Shared/_AdminLayout.cshtml";
 }
 else
 {
 layout = "~/Views/Shared/_Layout.cshtml";
 }

 Layout = layout;
}