微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从局部填充剃刀区

如何解决从局部填充剃刀区

我尝试这样做的主要动机是,仅在页面底部将部分代码与其余Javascript一起使用,而不是在呈现部分代码页面中间,获取Javascript。 这是我要执行的操作的简化示例: 这是在正文之前的“脚本”部分的布局。
<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href=\"@Url.Content(\"~/Content/Site.css\")\" rel=\"stylesheet\" type=\"text/css\" />    
</head>

<body>
    @RenderBody()
    <script src=\"@Url.Content(\"~/Scripts/jquery-1.4.4.min.js\")\" type=\"text/javascript\"></script>
    @RenderSection(\"Scripts\",false)
</body>
</html>
这是使用此布局的示例视图。
<h2>This is the view</h2>

@{Html.RenderPartial(\"_Partial\");}

@section Scripts {
<script type=\"text/javascript\">
        alert(\"I\'m a view.\");
</script>
}
这是从视图渲染的局部视图。
<p>This is the partial.</p>

@* this never makes it into the rendered page *@
@section Scripts {
<script type=\"text/javascript\">
    alert(\"I\'m a partial.\"); 
</script>
}
在此示例中,视图中指定的标记被放置到该部分中,而部分标记则没有。是否可以使用Razor从局部视图填充剖面?如果不是,那么还有什么其他方法获取Javascript,而这些Javascript只需要页面底部的局部对象而不全局包含它?     

解决方法

        我处理此问题的方法是为HtmlHelper类编写几个扩展方法。这样,局部视图就可以说它们需要脚本,然后在布局视图中将我调用的标记写入我的辅助方法以发出所需的脚本。 以下是辅助方法:
public static string RequireScript(this HtmlHelper html,string path,int priority = 1)
{
    var requiredScripts = HttpContext.Current.Items[\"RequiredScripts\"] as List<ResourceInclude>;
    if (requiredScripts == null) HttpContext.Current.Items[\"RequiredScripts\"] = requiredScripts = new List<ResourceInclude>();
    if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path,Priority = priority });
    return null;
}

public static HtmlString EmitRequiredScripts(this HtmlHelper html)
{
    var requiredScripts = HttpContext.Current.Items[\"RequiredScripts\"] as List<ResourceInclude>;
    if (requiredScripts == null) return null;
    StringBuilder sb = new StringBuilder();
    foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
    {
        sb.AppendFormat(\"<script src=\\\"{0}\\\" type=\\\"text/javascript\\\"></script>\\n\",item.Path);
    }
    return new HtmlString(sb.ToString());
}
public class ResourceInclude
{
    public string Path { get; set; }
    public int Priority { get; set; }
}
一旦有了适当的位置,您的局部视图便只需调用
@Html.RequireScript(\"/Path/To/Script\")
。 在布局视图的头部,您叫
@Html.EmitRequiredScripts()
。 另外一个好处是,它允许您清除重复的脚本请求。如果您有多个需要给定脚本的视图/局部视图,则可以放心地假设您只会输出一次     ,        部分视图无法参与其父视图的部分。     ,        您可能还有第二部分,仅负责注入必要的JavaScript。如果需要,在
@if
块附近放置几个脚本:
@model string
@if(Model == \"bla\") {
    <script type=\"text/javascript\">...</script>
}

@else if(Model == \"bli\") {
    <script type=\"text/javascript\">...</script>
}
显然可以清除一下,但是在视图的
Scripts
部分:
@section Scripts
{
    @Html.Partial(\"_Scripts\",\"ScriptName_For_Partial1\")
}
同样,它可能不会赢得美容大奖,但是会起作用。     ,        执行此操作的更优雅的方法是将部分视图脚本移到单独的文件中,然后在“视图的脚本”部分中呈现它:
<h2>This is the view</h2>

@Html.RenderPartial(\"_Partial\")

@section Scripts
{
    @Html.RenderPartial(\"_PartialScripts\")

    <script type=\"text/javascript\">
        alert(\"I\'m a view script.\");
    </script>
}
局部视图_Partial.cshtml:
<p>This is the partial.</p>
局部视图_PartialScripts.cshtml仅包含脚本:
<script type=\"text/javascript\">
    alert(\"I\'m a partial script!\");
</script>
    ,        安装Forloop.HtmlHelpers nuget软件包-它添加了一些用于在局部视图和编辑器模板中管理脚本的助手。 在布局中的某处,您需要致电
@Html.RenderScripts()
这将是在页面中输出任何脚本文件和脚本块的位置,因此我建议将其放在布局中的主要脚本之后和脚本部分(如果有的话)之后。 如果您正在结合使用Web优化框架,则可以使用重载
@Html.RenderScripts(Scripts.Render)
因此,此方法用于写出脚本文件。 现在,只要您想在视图,局部视图或模板中添加脚本文件或块,只需使用
@using (Html.BeginScriptContext())
{
  Html.AddScriptFile(\"~/Scripts/jquery.validate.js\");
  Html.AddScriptBlock(
    @<script type=\"text/javascript\">
       $(function() { $(\'#someField\').datepicker(); });
     </script>
  );
}
助手确保多次添加时仅呈现一个脚本文件引用,并且还确保按预期顺序呈现脚本文件,即 布局 局部和模板(按照它们在视图中出现的顺序,从上到下)     ,        [更新后的版本] @Necrocubus问题之后的更新版本,以包含嵌入式脚本。
public static class ScriptsExtensions
{
    const string REQ_SCRIPT = \"RequiredScript\";
    const string REQ_INLINESCRIPT = \"RequiredInlineScript\";
    const string REQ_STYLE = \"RequiredStyle\";

    #region Scripts
    /// <summary>
    /// Adds a script 
    /// </summary>
    /// <param name=\"html\"></param>
    /// <param name=\"path\"></param>
    /// <param name=\"priority\">Ordered by decreasing priority </param>
    /// <param name=\"bottom\"></param>
    /// <param name=\"options\"></param>
    /// <returns></returns>
    public static string RequireScript(this IHtmlHelper html,int priority = 1,bool bottom=false,params string[] options)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceToInclude>;
        if (requiredScripts == null) ctxt.Items[REQ_SCRIPT] = requiredScripts = new List<ResourceToInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceToInclude() { Path = path,Priority = priority,Options = options,Type=ResourceType.Script,Bottom=bottom});
        return null;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name=\"html\"></param>
    /// <param name=\"script\"></param>
    /// <param name=\"priority\">Ordered by decreasing priority </param>
    /// <param name=\"bottom\"></param>
    /// <returns></returns>
    public static string RequireInlineScript(this IHtmlHelper html,string script,bool bottom = false)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_INLINESCRIPT] as List<InlineResource>;
        if (requiredScripts == null) ctxt.Items[REQ_INLINESCRIPT] = requiredScripts = new List<InlineResource>();
        requiredScripts.Add(new InlineResource() { Content=script,Bottom=bottom,Type=ResourceType.Script});
        return null;
    }

    /// <summary>
    /// Just call @Html.EmitRequiredScripts(false)
    /// at the end of your head tag and 
    /// @Html.EmitRequiredScripts(true) at the end of the body if some scripts are set to be at the bottom.
    /// </summary>
    public static HtmlString EmitRequiredScripts(this IHtmlHelper html,bool bottom)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceToInclude>;
        var requiredInlineScripts = ctxt.Items[REQ_INLINESCRIPT] as List<InlineResource>;
        var scripts = new List<Resource>();
        scripts.AddRange(requiredScripts ?? new List<ResourceToInclude>());
        scripts.AddRange(requiredInlineScripts ?? new List<InlineResource>());
        if (scripts.Count==0) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in scripts.Where(s=>s.Bottom==bottom).OrderByDescending(i => i.Priority))
        {
            sb.Append(item.ToString());
        }
        return new HtmlString(sb.ToString());
    }
    #endregion Scripts

    #region Styles
    /// <summary>
    /// 
    /// </summary>
    /// <param name=\"html\"></param>
    /// <param name=\"path\"></param>
    /// <param name=\"priority\">Ordered by decreasing priority </param>
    /// <param name=\"options\"></param>
    /// <returns></returns>
    public static string RequireStyle(this IHtmlHelper html,params string[] options)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceToInclude>;
        if (requiredScripts == null) ctxt.Items[REQ_STYLE] = requiredScripts = new List<ResourceToInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceToInclude() { Path = path,Options = options });
        return null;
    }

    /// <summary>
    /// Just call @Html.EmitRequiredStyles()
    /// at the end of your head tag
    /// </summary>
    public static HtmlString EmitRequiredStyles(this IHtmlHelper html)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceToInclude>;
        if (requiredScripts == null) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
        {
            sb.Append(item.ToString());
        }
        return new HtmlString(sb.ToString());
    }
    #endregion Styles

    #region Models
    public class InlineResource : Resource
    {
        public string Content { get; set; }
        public override string ToString()
        {
            return \"<script>\"+Content+\"</script>\";
        }
    }

    public class ResourceToInclude : Resource
    {
        public string Path { get; set; }
        public string[] Options { get; set; }
        public override string ToString()
        {
            switch(Type)
            {
                case ResourceType.CSS:
                    if (Options == null || Options.Length == 0)
                        return String.Format(\"<link rel=\\\"stylesheet\\\" href=\\\"{0}\\\" type=\\\"text/css\\\" />\\n\",Path);
                    else
                        return String.Format(\"<link rel=\\\"stylesheet\\\" href=\\\"{0}\\\" type=\\\"text/css\\\" {1} />\\n\",Path,String.Join(\" \",Options));
                default:
                case ResourceType.Script:
                    if (Options == null || Options.Length == 0)
                        return String.Format(\"<script src=\\\"{0}\\\" type=\\\"text/javascript\\\"></script>\\n\",Path);
                    else
                        return String.Format(\"<script src=\\\"{0}\\\" type=\\\"text/javascript\\\" {1}></script>\\n\",Options));
            }
        }
    }
    public class Resource
    {
        public ResourceType Type { get; set; }
        public int Priority { get; set; }
        public bool Bottom { get; set; }
    }
    public enum ResourceType
    {
        Script,CSS
    }
    #endregion Models
}
我的2美分是一个旧帖子,但是仍然有用,因此这里是Bell先生与ASP.Net Core配合使用的解决方案的升级更新。 它允许从导入的局部视图和子视图向主布局添加脚本和样式,并可以向脚本/样式导入添加选项(例如异步延迟等):
public static class ScriptsExtensions
{
    const string REQ_SCRIPT = \"RequiredScript\";
    const string REQ_STYLE = \"RequiredStyle\";

    public static string RequireScript(this IHtmlHelper html,params string[] options)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceInclude>;
        if (requiredScripts == null) ctxt.Items[REQ_SCRIPT] = requiredScripts = new List<ResourceInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path,Options = options });
        return null;
    }


    public static HtmlString EmitRequiredScripts(this IHtmlHelper html)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceInclude>;
        if (requiredScripts == null) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
        {
            if (item.Options == null || item.Options.Length == 0)
                sb.AppendFormat(\"<script src=\\\"{0}\\\" type=\\\"text/javascript\\\"></script>\\n\",item.Path);
            else
                sb.AppendFormat(\"<script src=\\\"{0}\\\" type=\\\"text/javascript\\\" {1}></script>\\n\",item.Path,item.Options));

        }
        return new HtmlString(sb.ToString());
    }


    public static string RequireStyle(this IHtmlHelper html,params string[] options)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceInclude>;
        if (requiredScripts == null) ctxt.Items[REQ_STYLE] = requiredScripts = new List<ResourceInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path,Options = options });
        return null;
    }


    public static HtmlString EmitRequiredStyles(this IHtmlHelper html)
    {
        var ctxt = html.ViewContext.HttpContext;

        var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceInclude>;
        if (requiredScripts == null) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
        {
            if (item.Options == null || item.Options.Length == 0)
                sb.AppendFormat(\"<link rel=\\\"stylesheet\\\" href=\\\"{0}\\\" type=\\\"text/css\\\" />\\n\",item.Path);
            else
                sb.AppendFormat(\"<link rel=\\\"stylesheet\\\" href=\\\"{0}\\\" type=\\\"text/css\\\" {1} />\\n\",item.Options));
        }
        return new HtmlString(sb.ToString());
    }


    public class ResourceInclude
    {
        public string Path { get; set; }
        public int Priority { get; set; }
        public string[] Options { get; set; }
    }
}
    ,        对于那些寻求aspnet core 2.0版本的用户:
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.AspNetCore.Html;
    using Microsoft.AspNetCore.Http;

    public static class HttpContextAccessorExtensions
    {
        public static string RequireScript(this IHttpContextAccessor htmlContextAccessor,int priority = 1)
        {
            var requiredScripts = htmlContextAccessor.HttpContext.Items[\"RequiredScripts\"] as List<ResourceInclude>;
            if (requiredScripts == null) htmlContextAccessor.HttpContext.Items[\"RequiredScripts\"] = requiredScripts = new List<ResourceInclude>();
            if (requiredScripts.All(i => i.Path != path)) requiredScripts.Add(new ResourceInclude() { Path = path,Priority = priority });
            return null;
        }

        public static HtmlString EmitRequiredScripts(this IHttpContextAccessor htmlContextAccessor)
        {
            var requiredScripts = htmlContextAccessor.HttpContext.Items[\"RequiredScripts\"] as List<ResourceInclude>;
            if (requiredScripts == null) return null;
            StringBuilder sb = new StringBuilder();
            foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
            {
                sb.AppendFormat(\"<script src=\\\"{0}\\\" type=\\\"text/javascript\\\"></script>\\n\",item.Path);
            }
            return new HtmlString(sb.ToString());
        }
        public class ResourceInclude
        {
            public string Path { get; set; }
            public int Priority { get; set; }
        }
    }
在脚本渲染部分调用之后添加到布局中:
@HttpContextAccessor.EmitRequiredScripts()
在您的局部视图中:
@inject IHttpContextAccessor HttpContextAccessor

...

@HttpContextAccessor.RequireScript(\"/scripts/moment.min.js\")
    ,        根据上面的Bell And Shimmy先生的回答,我为Bundle脚本添加了额外的功能。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Web.Mvc;
namespace ABC.Utility
{
public static  class PartialViewHelper
{
    public static string RequireScript(this HtmlHelper html,int priority = 1)
    {
        var requiredScripts = HttpContext.Current.Items[\"RequiredScripts\"] as List<ResourceInclude>;
        if (requiredScripts == null) HttpContext.Current.Items[\"RequiredScripts\"] = requiredScripts = new List<ResourceInclude>();
        if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path,Priority = priority });
        return null;
    }

    public static string RequireBundleStyles(this HtmlHelper html,string bundleName)
    {
        var a = System.Web.Optimization.Styles.Render(bundleName);
        var requiredStyles = HttpContext.Current.Items[\"RequiredStyles\"] as IHtmlString;
        if (requiredStyles == null) HttpContext.Current.Items[\"RequiredStyles\"] = requiredStyles = a;
        return null;
    }

    public static string RequireBundleScripts(this HtmlHelper html,string bundleName)
    {
        var a=System.Web.Optimization.Scripts.Render(bundleName);
        var requiredScripts = HttpContext.Current.Items[\"RequiredScripts\"] as IHtmlString;
        if (requiredScripts == null) HttpContext.Current.Items[\"RequiredScripts\"] = requiredScripts = a;
        return null;
    }

    public static HtmlString EmitRequiredBundleStyles(this HtmlHelper html)
    {
        var requiredStyles = HttpContext.Current.Items[\"RequiredStyles\"] as IHtmlString;
        if (requiredStyles == null) return null;
        return MvcHtmlString.Create(requiredStyles.ToHtmlString()) ;
    }

    public static HtmlString EmitRequiredBundleScripts(this HtmlHelper html)
    {
        var requiredScripts = HttpContext.Current.Items[\"RequiredScripts\"] as IHtmlString;
        if (requiredScripts == null) return null;
        return MvcHtmlString.Create(requiredScripts.ToHtmlString());
    }

    public static HtmlString EmitRequiredScripts(this HtmlHelper html)
    {
        var requiredScripts = HttpContext.Current.Items[\"RequiredScripts\"] as List<ResourceInclude>;
        if (requiredScripts == null) return null;
        StringBuilder sb = new StringBuilder();
        foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
        {
            sb.AppendFormat(\"<script src=\\\"{0}\\\" type=\\\"text/javascript\\\"></script>\\n\",item.Path);
        }
        return new HtmlString(sb.ToString());
    }
    public class ResourceInclude
    {
        public string Path { get; set; }
        public int Priority { get; set; }
    }
}//end class
}// end namespace  
在PartialView上的样本:-     @ Html.RequireBundleStyles(\“〜/ bundles / fileupload / bootstrap / BasicPlusUI / css \”);     @ Html.RequireBundleScripts(\“〜/ bundles / fileupload / bootstrap / BasicPlusUI / js \”); 在MasterPage上采样:-     @ Html.EmitRequiredBundleStyles()     ,        使用答案https://stackoverflow.com/a/18790222/1037948中的
@using(Html.Delayed()){ ...your content... }
扩展名可以在页面稍后部分呈现任何内容(脚本或仅HTML)。内部
Queue
应确保正确订购。     ,ClientDependency.Core.Mvc.dll中也实现了此功能。它提供了html帮助器:@ Html.RequiresJs和@ Html.RenderJsHere()。 Nuget包:ClientDependency-Mvc     ,        您可以创建一个新的“ 24”页面,并将PartialView包裹在全视图内部,该全视图负责呈现内容以及任何库部分。 例如,假设我有以下代码:
HomeController.cs
[HttpGet]
public ActionResult About()
{
    var vm = new AboutViewModel();
    return View(\"About\",vm);
}
呈现“全页”视图时,通常是通过合并两个文件来呈现的:
About.cshtml
@model AboutViewModel

@{
    ViewBag.Title = \"About CSHN\";
}

<h3>@ViewBag.Title</h3>

@section Styles {
    <style> /* style info here */ </style>
}

@section Scripts {
    <script> /* script info here */ </script>
}
_Layout.cshtml
(或_ViewStart中指定或在页面中覆盖的任何内容)
<!DOCTYPE html>

<html>
<head>
    @RenderSection(\"Styles\",false)
    <title>@ViewBag.Title</title>
</head>
<body>
    @RenderBody()

    @RenderSection(\"scripts\",false)
</body>
</html>
现在,假设您想将“ 27”渲染为部分视图,或者作为响应AJAX调用的模态窗口。这里的目标是仅返回About页面,脚本和所有内容中指定的内容,而不会使
_Layout.cshtml
主布局中包含所有浮夸的内容(如完整的
<html>
文档)。 您可以这样尝试,但它不会附带任何节块:
return PartialView(\"About\",vm);
而是添加一个更简单的布局页面,如下所示:
_PartialLayout.cshtml
<div>
    @RenderBody()
    @RenderSection(\"Styles\",false)
    @RenderSection(\"scripts\",false)
</div>
或者支持这样的模式窗口:
_ModalLayout.cshtml
<div class=\"modal modal-page fade\" tabindex=\"-1\" role=\"dialog\" >
    <div class=\"modal-dialog modal-lg\" role=\"document\">
        <div class=\"modal-content\">

            <div class=\"modal-header\">
                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\"><span aria-hidden=\"true\">&times;</span></button>
                <h4 class=\"modal-title\">@ViewBag.Title</h4>
            </div>

            <div class=\"modal-body\">

                @RenderBody()
                @RenderSection(\"Styles\",false)
                @RenderSection(\"scripts\",false)

            </div>
            <div class=\"modal-footer\">
                <button type=\"button\" class=\"btn btn-inverse\" data-dismiss=\"modal\">Dismiss</button>
            </div>
        </div>
    </div>
</div>
然后,您可以在此控制器或要同时呈现视图内容和脚本的任何其他处理程序中指定自定义主视图。
[HttpGet]
public ActionResult About()
{
    var vm = new AboutViewModel();
    return !Request.IsAjaxRequest()
              ? View(\"About\",vm)
              : View(\"About\",\"~/Views/Shared/_ModalLayout.cshtml\",vm);
}
    ,        这是我对“如何将部分视图从部分视图注入到asp.net mvc的主视图或主布局视图中的部分?”的解决方案。如果使用关键字“部分+部分”对stackoverflow进行搜索,则会获得大量相关问题和给出的答案,但是根据剃刀引擎语法,这些问题对我而言似乎都不是很优雅。因此,我只看一下Razor引擎,看看是否可以找到更好的解决方案。 幸运的是,我发现Razor引擎如何为视图模板文件(* .cshtml,*。vbhtml)进行编译对我来说很有趣。 (我将在后面解释),下面是我的解决方案代码,我认为使用起来非常简单,优雅。
namespace System.Web.Mvc.Html
{
    public static class HtmlHelperExtensions
    {
        /// <summary>
        /// 确保所有视图,包括分部视图(PartialView)中的节(Section)定义被按照先后顺序追加到最终文档输出流中
        /// </summary>
        public static MvcHtmlString EnsureSection(this HtmlHelper helper)
        {
            var wp = (WebViewPage)helper.ViewDataContainer;
            Dictionary<string,WebPages.SectionWriter> sw = (Dictionary<string,WebPages.SectionWriter>)typeof(WebPages.WebPageBase).GetProperty(\"SectionWriters\",Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance).GetValue(wp);
            if (!helper.ViewContext.HttpContext.Items.Contains(\"SectionWriter\"))
            {
                Dictionary<string,Stack<WebPages.SectionWriter>> qss = new Dictionary<string,Stack<WebPages.SectionWriter>>();
                helper.ViewContext.HttpContext.Items[\"SectionWriter\"] = qss;
            }
            var eqs = (Dictionary<string,Stack<WebPages.SectionWriter>>)helper.ViewContext.HttpContext.Items[\"SectionWriter\"];
            foreach (var kp in sw)
            {
                if (!eqs.ContainsKey(kp.Key)) eqs[kp.Key] = new Stack<WebPages.SectionWriter>();
                eqs[kp.Key].Push(kp.Value);
            }
            return MvcHtmlString.Create(\"\");
        }

        /// <summary>
        /// 在文档流中渲染指定的节(Section)
        /// </summary>
        public static MvcHtmlString RenderSectionEx(this HtmlHelper helper,string section,bool required = false)
        {
            if (helper.ViewContext.HttpContext.Items.Contains(\"SectionWriter\"))
            {
                Dictionary<string,Stack<WebPages.SectionWriter>> qss = (Dictionary<string,Stack<WebPages.SectionWriter>>)helper.ViewContext.HttpContext.Items[\"SectionWriter\"];
                if (qss.ContainsKey(section))
                {
                    var wp = (WebViewPage)helper.ViewDataContainer;
                    var qs = qss[section];
                    while (qs.Count > 0)
                    {
                        var sw = qs.Pop();
                        var os = ((WebViewPage)sw.Target).OutputStack;
                        if (os.Count == 0) os.Push(wp.Output);
                        sw.Invoke();
                    }
                }
                else if (!qss.ContainsKey(section) && required)
                {
                    throw new Exception(string.Format(\"\'{0}\' section is not defined.\",section));
                }
            }
            return MvcHtmlString.Create(\"\");
        }
    }
}
用法:使用代码也很简单,并且看起来与通常的样式几乎相同。它还支持嵌套部分视图的任何级别。即。我有一个视图模板链:_ViewStart.cshtml-> layout.cshtml-> index.cshtml-> [head.cshtml,foot.cshtml]-> ad.cshtml。 在layout.cshtml中,我们有:
<!DOCTYPE html>
<html>
<head lang=\"en\">
    <meta charset=\"UTF-8\">
    <title>@ViewBag.Title - @ViewBag.WebSetting.Site.WebName</title>
    <base href=\"@ViewBag.Template/\" />
    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">
    <meta http-equiv=\"Cache-Control\" content=\"no-siteapp\" />
    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1,maximum-scale=1.0,user-scalable=0,user-scalable=no\">
    <meta name=\"format-detection\" content=\"telephone=no\">
    <meta name=\"renderer\" content=\"webkit\">
    <meta name=\"author\" content=\"Taro Technology Co.,LTD\" />
    <meta name=\"robots\" content=\"index,follow\" />
    <meta name=\"description\" content=\"\" />
    <meta name=\"keywords\" content=\"\" />
    <link rel=\"alternate icon\" type=\"@ViewBag.WebSetting.Site.WebFavIcon\" href=\"@ViewBag.WebSetting.Site.WebFavIcon\">
    @Html.RenderSectionEx(\"Head\")
</head>
<body>
    @RenderBody()
    @Html.RenderSectionEx(\"Foot\")
</body>
</html>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。