【问题标题】:MVC Render section scripts in controller控制器中的 MVC 渲染部分脚本
【发布时间】:2020-04-11 22:17:08
【问题描述】:

我想将控制器内的 .cshtml 视图的“脚本”部分呈现为字符串。这可能吗?

我真正想做的是使用单独的 ajax 调用获取脚本,然后在加载视图的 html 后也使用 ajax 在脚本上运行 eval。

我已尝试寻找相关主题,但没有找到任何相关内容。一些相关的答案与HtmlHelper.ViewContext.HttpContext.Items[""] 混在一起,但我不确定如何使用它。

我想要的是这样的:string scripts = GetScriptsForView(action, controller); 它返回视图中使用的部分,如下所示:@section Scripts {

澄清(编辑):

我正在尝试用 ajax 调用替换布局页面的“RenderBody()”,这样我就不必每次都加载包含静态标题的布局。

我已经设法用 ajax 调用替换了所有 <a>-tags,替换了包含视图的 <div>,但我无法让 javascripts 工作。

我可以从 cshtml 文件中删除 @section scripts { 并让脚本标签与 html 视图一起加载。这样做的问题是,如果我重新加载页面,它会在调用布局页面的脚本之前调用该视图的脚本,从而导致错误。因此我希望单独加载脚本。

【问题讨论】:

  • 与其解释你想要什么,不如试着解释原因,或者你尝试过的任何事情。视图中需要的脚本是动态的吗?
  • @AsheraH 很确定我解释了原因。 What I want to do is get the scripts with a separate ajax call and then run eval on the script after loading the html of the view also with ajax.。这是为了动态加载cshtml视图的脚本部分。
  • 你为什么要这样做?您尝试使用此解决方案解决的实际问题是什么?对我来说,它看起来像XY problem。如果你加载一个部分视图,它有一个脚本标签,并且在文档中准备了一些代码,那么你会做同样的事情。
  • 我想使用 ajax 加载没有布局的视图。脚本在脚本部分,没有布局文件就不会包含在内。
  • 如果您返回PartialView(),它将返回不带布局且不带脚本部分的视图。如果您也想要脚本,只需返回 View() 它将包括布局和脚本部分。

标签: c# asp.net .net asp.net-mvc razor


【解决方案1】:

TL;DR

虽然您可以在单独的请求中加载部分和内容(参见示例 1),但您不需要这样做。而是:

  • 您可以有不同的Layout 页面用于不同的目的,并动态决定视图使用哪种布局。例如,用于普通请求的完整布局页面和用于 ajax 请求的不带页眉和页脚的简单布局页面(参见示例 2)。

  • 您可以根据不同的请求参数,如Request.HeadersRequest.QueryStringRequest.IsAjaxRequest等,在_ViewStart.cstml或控制器中动态决定布局页面。

    李>

长答案

这里有一些关于布局、部分、视图和局部视图的有用说明,可以帮助您处理这种情况:

  • 在返回 View() 中指定布局 - 返回 View 时,您可以指定视图的布局。例如返回View("Index", masterName: "_SomeLaypout")。您可以有一些逻辑来动态决定布局名称。

  • 在_LayoutStart.cshtml中指定布局 - 返回View时,您可以在_ViewStart.cshtml文件中指定Layout,例如@{ Layout = "_Layout"; }。您可以有一些逻辑来动态决定布局名称。

  • 不带布局渲染内容 - 当使用PartialView() 方法返回视图时,它将不带任何布局或不渲染任何部分渲染视图的全部内容。相当于在_ViewStart.cshtml中使用return View并将Layout设置为null)

  • 渲染没有任何内容的部分 - 您可以拥有一个只有 RenderSection 方法的布局。然后,如果您使用该布局返回一个视图,它只会呈现该视图的指定部分并忽略其内容。

  • 带/不带部分的脚本 - 考虑到上述选项,当您将脚本放入脚本标记中而不放入 Section 时,您保证它们将作为结果的一部分返回,不管调用 return View 或 return PartialView 或有或没有 Layout。所以在某些情况你可能想要放置没有节的脚本。在这种情况下,当您使用 ajax 调用加载局部视图时,它会包含局部视图的内容和脚本。
    在某些情况下,即使是局部视图,您也可能希望拥有一些通用内容/脚本,在这种情况下,您可以使用 Section,也有一个 Layout 页面来呈现该部分并包含您希望在所有局部视图中拥有的通用内容。在这种情况下,您需要使用 return View 返回部分视图并指定特定的布局页面。

示例 1 - 仅返回脚本或仅返回 ajax 请求中的内容

以下示例显示了如何发送 ajax 请求以获取内容和发送 ajax 请求以获取脚本部分。

请注意,我不建议使用不同的请求来获取 内容或单独获取脚本,此示例仅适用于 学习目的是向您展示您可以使用Layout 页面和 _ViewStart.

为此,请按以下步骤操作:

  1. _ViewStart.cshtml内容更改为:

    @{
        if(Request.QueryString["Layout"]=="_Body")
        {
            //Just content of the page, without layout or any section
            Layout = null; 
        }
        else if (Request.QueryString["Layout"] == "_Script")
        {
            //Just script section
            Layout = "~/Views/Shared/_Script.cshtml"; 
        }
        else
        {
            //Everything, layout, content, section
            Layout = "~/Views/Shared/_Layout.cshtml"; 
        }
    }
    

    注意:根据您的要求,您可以轻松地依赖 Request.HeaderRequest.IsAjaxRequest() 或 ... 而不是 Request.QueryString。 p>

  1. 然后只为_Script 添加一个名为_script.cshtml 的新布局页面,其内容如下:

    @RenderSection("scripts", required: false)
    
  2. 然后:

    • 要获取脚本部分,请发送一个普通的 ajax 请求并添加以下查询字符串:Layout=_Script

    • 要获取没有脚本部分的内容,发送一个普通的ajax请求并添加以下查询字符串:Layout=_Body

    • 要获取全部内容,发送一个普通的 ajax 请求而不指定任何布局查询字符串。

    例如,假设您在Home 控制器中有一个Sample 操作:

    [HttpGet]
    public ActionResult Sample()
    {
        return View();
    }
    

    返回以下Sample.cshtml 视图:

    <div id="div1" style="border:1px solid #000000;">
        some content
    </div>
    @section scripts {
        <script>
            $(function () {
                alert('Hi');
            });
        </script>
    }
    

    在客户端,获取脚本部分:

    <button id="button1">Get Sample Content</button>
    <script>
        $(function () {
            $('#button1').click(function () {
                $.ajax({
                    url: '/home/sample',
                    data: { Layout: '_Script' },
                    type: 'GET',
                    cache: false,
                    success: function (data) { alert(data); },
                    error: function () { alert('error'); }
                });
            });
        });
    <script>
    

示例 2 - 使用 Ajax 请求返回没有布局的内容

在此示例中,您可以看到如何轻松返回视图的内容和脚本,而无需为 ajax 请求进行布局。

为此,请按以下步骤操作:

  1. _ViewStart.cshtml内容更改为:

    @{
        if(Request.IsAjaxRequest())
        {
            Layout = "~/Views/Shared/_Partial.cshtml";
        }
        else 
        {
            Layout = "~/Views/Shared/_Layout.cshtml";
        }
    }
    
  2. 添加一个名为_PartialView.cshtml 的新布局页面,其内容如下:

    @RenderBody()
    @RenderSection("scripts", required: false)
    
  3. 使用 ajax 获取视图。例如,假设您在Home 控制器中有一个Sample 操作:

    [HttpGet]
    public ActionResult Sample()
    {
        return View();
    }
    

    返回以下Sample.cshtml 视图:

    <div id="div1" style="border:1px solid #000000;">
        some content
    </div>
    @section scripts {
        <script>
            $(function () {
                alert('Hi');
            });
        </script>
    }
    

    使用ajax获取结果:

    <button id="button1">Get Sample Content</button>
    <script>
        $(function () {
            $('#button1').click(function () {
                $.ajax({
                    url: '/home/sample',
                    type: 'GET',
                    cache: false,
                    success: function (data) { alert(data); },
                    error: function () { alert('error'); }
                });
            });
        });
    <script>
    

【讨论】:

    【解决方案2】:

    据我了解,我猜您正在寻找通过 Ajax 加载页面而不重新加载整个页面。

    你检查了Kool Swap Jquery 插件吗?希望这能满足您的要求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-28
      相关资源
      最近更新 更多