Q:

ASP MVC Trying to load layout from string Model

I'm trying to load a simple view
@model string
@{
    ViewBag.Title = "TestPage";
    Layout = "~/Views/Shared/" + Model + ".cshtml";
}
<style>
    body {
        background-color: black;
    }
</style>
<h2>Page_Import</h2>

And as you can probably see, I'm trying to pass the name of the layout page from the controller, 
    using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace mvcRockslide03.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult TestImport()
        {
            return View("_Layout");
        }
    }
}

but when I open the page, I get the following error:
Server Error in '/' Application.

The file "~/Views/Shared/Forum_Layout.cshtml" cannot be requested directly because it calls the "RenderSection" method.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: The file "~/Views/Shared/Forum_Layout.cshtml" cannot be requested directly because it calls the "RenderSection" method.

Source Error: 

Line 8:  <body>
Line 9:      <div class="content-wrapper">        
Line 10:         @RenderSection("featured", required: false)
Line 11:         <section class="content-wrapper main-content clear-fix">
Line 12:         @RenderBody()

Source File: f:\mvcRockslide03\mvcRockslide03\Views\Shared\Forum_Layout.cshtml    Line: 10 

but when I change
@model string
@{
    Layout = "~/Views/Shared/" + Model + ".cshtml";
}

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

in the view
and
public ActionResult TestImport()
{
    return View("_Layout");
}

to
public ActionResult TestImport()
    {
        return View();
    }

in the HomeController,
it works fine.
I'm really stumped and any help would be vastly appreciated.
Thanks,
JMiller

A:

This is because of the overloads of the View() function.  If you pass only a string, it thinks you are telling it the actual name of the view to load and not passing a simple model of type string.  
For example, the View() function cannot distinguish between:
return View("~/Views/Home/myView.cshtml");

and
return View("_Layout");

There are a few ways around this that I can think of.
1.Use ViewData[] to hold your layout view name.
Controller
public ActionResult TestImport()
{
    ViewData["layout"] = "_Layout"
    return View();
}

View
@{
    Layout = "~/Views/Shared/" + ViewData["layout"] + ".cshtml";
}

2.Strongly type the name of the view and as a second parameter, pass the layout string
Controller
public ActionResult TestImport()
{
    return View("TestImport", "_Layout");
}

3.Create a model that has a string property and pass that back to the view.
Model Class
public class LayoutModel{

  public string LayoutName {get;set;}
}

Controller
public ActionResult TestImport()
{
    return View(new LayoutModel{LayoutName = "_Layout"});
}

View
@model LayoutModel
@{
    Layout = "~/Views/Shared/" + Model.LayoutName + ".cshtml";
}

