如何将代码放在 PartialView 的 <head> 或 <body> 元素中以避免代码重复?

How can I place code in the <head> or <body> element from a PartialView so as to avoid code repetition?

我正在为我的所有视图以 <script> 标签的形式和形状从数据库中检索统计信息,其中一些将进入 <head>,其他进入 [=18] =].

其中一些信息由所有视图共享,例如 Google 分析,但其他信息仅特定于某些视图,例如仅在订单确认视图中可用的订单详细信息。

最终结果必须是:

<head>
    <script><!-- Google Analytics --></script>
</head>

我在布局中使用命名部分来实现我想要的:

<head>
    @RenderSection("headScripts", required: false)
</head>

<body>
    @RenderSection("bodyScripts", required: false)
</body>

示例查看代码为:

@if ((Model.Scripts.Head != null) && (Model.Scripts.Head.Count() != 0))
{

    <text>
    @section headScripts
    {
        @foreach (var script in Model.Scripts.Head)
        {
            @Html.Raw(@script.Code);
        }
    }
    </text>

}

所有视图模型都继承自带有 Scripts 字段的基础 class,并且我上面粘贴的代码在我的所有视图中都被复制,这是一个问题。

我试图将代码移动到 PartialView,从布局中 </body> 正下方的这一行开始:

@{Html.RenderAction("Index", "Scripts");}

在我的 ScriptsController 中:

public ActionResult Index()
{
    Scripts scripts = new Scripts();
    scripts.Head = whatever comes from the database;
    scripts.Body = whatever comes from the database;    

    return PartialView("/Views/Shared/scripts.cshtml", scripts);
}

一切正常,模型已正确填充并在脚本部分视图中可用,但不幸的是 @section 无法在部分视图中调用,因此 <script> 标签未显示。

是否有任何变通方法可以将 @if ((Model.Scripts.Head != null) && (Model.Scripts.Head.Count() != 0)) 和其余代码放在所有视图使用的一个公共位置?

也许可以这样做

<head>
    @RenderSection("headScripts", required: false)
    @Html.RenderAction("HeadScripts", "Scripts")
</head>

<body>
    @RenderSection("bodyScripts", required: false)
    @Html.RenderAction("BodyScripts", "Scripts")
</body>

然后在您的脚本控制器中,每次调用都会有两种方法

public ActionResult HeadScripts()
{
    Scripts scripts = new Scripts();
    scripts.Head = whatever comes from the database;    

    return PartialView("/Views/Shared/scripts.cshtml", scripts);
}

public ActionResult BodyScripts()
{
    Scripts scripts = new Scripts();
    scripts.Body = whatever comes from the database;    

    return PartialView("/Views/Shared/scripts.cshtml", scripts);
}

希望对您有所帮助

编辑: 同样在 PartialView 中,您将不再需要 @section

@if ((Model.Scripts.Head != null) && (Model.Scripts.Head.Count() != 0))
{
    @foreach (var script in Model.Scripts.Head)
    {
        @Html.Raw(@script.Code);
    }
}

编辑 2: 使用 BaseControllerViewBag

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
       ViewBag.HeadStart = whatever comes from the database;
       ViewBag.HeadEnd = whatever comes from the database;
       ViewBag.BodyStart = whatever comes from the database;
       ViewBag.BodyEnd = whatever comes from the database;
    }
}

然后在每个控制器中,您将从该基本控制器继承

public class HomeController : BaseController
{
    // some methods here
}

终于在视图中

<head>
    @if (ViewBag.HeadStart != null)
    {
        @foreach (var script in ViewBag.HeadStart)
        {
           @Html.Raw(@script.Code);
        }
    }

    @RenderSection("headScripts", required: false)
    @* do the same for end *@
</head>
<body>
@* same thing here as well *@
</body>