2

I have two action called "a" and "b". also I have two view for them. the layout of these views is difference. for a:

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

for b:

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

also the Error view is shared.

How can I use a dynamic layout for Error view. for example when an error occurred while processing action "a" the error show in layout of action "a" and if an error occurred while processing action "b" the error show in layout of action "b"?

Sergi Papaseit
  • 15,999
  • 16
  • 67
  • 101
Ghooti Farangi
  • 19,926
  • 15
  • 46
  • 61
  • http://stackoverflow.com/questions/5059323/asp-mvc-3-use-different-layouts-in-different-views – Adam Apr 05 '13 at 14:45

4 Answers4

6

You could write a helper method:

public static string GetLayout(this HtmlHelper htmlHelper)
{
    var action = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
    if (string.Equals("a", action, StringComparison.OrdinalIgnoreCase))
    {
        return "~/Views/Shared/_X.cshtml";
    } 
    else if (string.Equals("b", action, StringComparison.OrdinalIgnoreCase))
    {
        return "~/Views/Shared/_Y.cshtml";
    }
    return "~/Views/Shared/_Layout.cshtml";
}

and then:

@{
    Layout = Html.GetLayout();
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
1

hope this help u....various way of rendering layouts in Asp.Net MVC.

Method 1 : Control Layouts rendering by using _ViewStart file in the root directory of the Views folder

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

Method 2 : Return Layout from ActionResult

We can also override the default layout rendering by returning the layout from the ActionResult by using the below code:

public ActionResult Index()
{
RegisterModel model = new RegisterModel();
//TO DO:
return View("Index", "_AdminLayout", model);
}

Method 3 : Define Layout with in each view on the top

We can also override the default layout rendering by defining the layout on the view by using the below code:

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

thanks

Thomas
  • 33,544
  • 126
  • 357
  • 626
1

How about this overload?

Controller.View Method (String, String) (System.Web.Mvc)

in a action

  return View(viewName,"_X");

in b action

  return View(viewName,"_Y";
takepara
  • 10,413
  • 3
  • 34
  • 31
0

You could try and pass the layout from the controller action: set the current layout in the session and then retrieve it in your error controller and pass it to the view through the ViewBag property:

public ActionResult A()
{
    // Do things

    // Set the layout
    Session["currentLayout"] = "~/Views/Shared/_X.cshtml";

    return View();
}

ErrorController:

public ActionResult NotFound() // 404
{
    // Set the layout
    ViewBag.ErrorLayout = Session["currentLayout"];

    return View();
}

then in your error view:

@{
    Layout = ViewBag.ErrorLayout;
}

I'll grant you this will not win a beauty prize; there might be other ways.

For example, take a look at this answer for how to set the layout in an ActionFilter: How to set a Razor layout in MVC via an attribute filter?

You could write your own Error Filter inheriting from HandleError and set the layout in there.

Community
  • 1
  • 1
Sergi Papaseit
  • 15,999
  • 16
  • 67
  • 101