如何在View&PartialView(合并)中多次使用Razor Section而不覆盖它?

Ale*_*bin 32 razor asp.net-mvc-3

在_Layout.cshtml文件中,我在主体底部有一个名为"ScriptsContent"的部分,声明如下:

@RenderSection("ScriptsContent", required: false)
Run Code Online (Sandbox Code Playgroud)

在我看来,我可以使用此部分添加要执行的脚本.但是,如果我还有一个PartialView也需要使用此部分来添加其他脚本呢?

视图

@section ScriptsContent
{
    <script type="text/javascript">
        alert(1);
    </script>
}

@Html.Partial("PartialView")
Run Code Online (Sandbox Code Playgroud)

PartialView

@section ScriptsContent
{
    <script type="text/javascript">
        alert(2);
    </script>
}
Run Code Online (Sandbox Code Playgroud)

结果

仅渲染第一个脚本.第二个脚本不存在于网页的源代码中.

Razor似乎只输出他看到的第一个@section ScriptsContent.我想知道的是,是否有办法将每个调用合并到该部分.

如果我们不能这样做,你有什么建议?

感谢您的帮助!

UPDATE

我找到了一些解决问题的代码.请参阅下面的答案.

Ale*_*bin 7

这是该问题的解决方案.它来自这个博客:http://blog.logrythmik.com/post/A-Script-Block-Templated-Delegate-for-Inline-Scripts-in-Razor-Partials.aspx

public static class ViewPageExtensions
{        
    private const string SCRIPTBLOCK_BUILDER = "ScriptBlockBuilder";

    public static MvcHtmlString ScriptBlock(this WebViewPage webPage, Func<dynamic, HelperResult> template)
    {
        if (!webPage.IsAjax)
        {
            var scriptBuilder = webPage.Context.Items[SCRIPTBLOCK_BUILDER] as StringBuilder ?? new StringBuilder();

            scriptBuilder.Append(template(null).ToHtmlString());
            webPage.Context.Items[SCRIPTBLOCK_BUILDER] = scriptBuilder;

            return new MvcHtmlString(string.Empty);
        }

        return new MvcHtmlString(template(null).ToHtmlString());
    }

    public static MvcHtmlString WriteScriptBlocks(this WebViewPage webPage)
    {
        var scriptBuilder = webPage.Context.Items[SCRIPTBLOCK_BUILDER] as StringBuilder ?? new StringBuilder();

        return new MvcHtmlString(scriptBuilder.ToString());
    }
}
Run Code Online (Sandbox Code Playgroud)

所以在View或PartialView中你可以使用这个:

@this.ScriptBlock(
    @<script type='text/javascript'>
        alert(1);
    </script>
)
Run Code Online (Sandbox Code Playgroud)

并在您的_Layout或MasterView中,使用此:

@this.WriteScriptBlocks()
Run Code Online (Sandbox Code Playgroud)

  • 我不推荐这种方法,因为你第一次在控制器动作上使用``OutputCache``属性时会遇到麻烦.因为在显式的部分视图中没有任何内容呈现,所以如果第一个请求被缓存,脚本块将不会呈现两次.另请参阅此处的评论:http://stackoverflow.com/a/15363037/1823162 (2认同)