부분에서 Razor 섹션 채우기
이 작업을 수행하는 주된 동기는 부분이 렌더링되는 페이지의 중간이 아니라 나머지 Javascript와 함께 페이지 하단의 부분에만 필요한 Javascript를 얻는 것입니다.
다음은 내가하려는 작업의 간단한 예입니다.
다음은 본문 바로 앞에 Scripts 섹션이있는 레이아웃입니다.
<!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를 사용하여 부분보기에서 섹션을 채울 수 있습니까? 그렇지 않다면, 페이지 하단의 부분에만 필요한 자바 스크립트를 전역 적으로 포함하지 않고 얻는 다른 방법은 무엇입니까?
이 문제를 처리 한 방법은 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()
.
이것의 추가 보너스는 중복 스크립트 요청을 걸러 낼 수 있다는 것입니다. 주어진 스크립트가 필요한 여러보기 / 부분보기가있는 경우 한 번만 출력한다고 안전하게 가정 할 수 있습니다.
부분보기는 상위보기 섹션에 참여할 수 없습니다.
필요한 자바 스크립트 삽입만을 담당하는 두 번째 부분을 가질 수 있습니다. @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 너겟 패키지를 설치하십시오 -부분보기 및 편집기 템플릿에서 스크립트를 관리하기위한 일부 도우미를 추가합니다.
레이아웃 어딘가에 전화해야합니다.
@Html.RenderScripts()
이것은 모든 스크립트 파일과 스크립트 블록이 페이지에 출력되는 곳이므로 레이아웃의 기본 스크립트 뒤와 스크립트 섹션 뒤에 넣는 것이 좋습니다 (있는 경우).
번들링과 함께 웹 최적화 프레임 워크를 사용하는 경우 오버로드를 사용할 수 있습니다.
@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, string path, 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, int priority = 1, 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, Priority = priority, 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, string path, int priority = 1, 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, Priority = priority, 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", Path, String.Join(" ", 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 센트, 그것은 오래된 게시물이지만 여전히 관련성이 있으므로 여기에 ASP.Net Core와 함께 작동하는 Mr Bell의 솔루션의 업그레이드 된 업데이트가 있습니다.
가져온 부분보기 및 하위보기에서 기본 레이아웃에 스크립트와 스타일을 추가하고 스크립트 / 스타일 가져 오기에 옵션을 추가 할 수 있습니다 (예 : 비동기 지연 등).
public static class ScriptsExtensions
{
const string REQ_SCRIPT = "RequiredScript";
const string REQ_STYLE = "RequiredStyle";
public static string RequireScript(this IHtmlHelper html, string path, int priority = 1, 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, Priority = priority, 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, String.Join(" ", item.Options));
}
return new HtmlString(sb.ToString());
}
public static string RequireStyle(this IHtmlHelper html, string path, int priority = 1, 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, Priority = priority, 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.Path, String.Join(" ", 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 코어 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, string path, 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")
위의 Mr 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, 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 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 ()
@using(Html.Delayed()){ ...your content... }
답변 https://stackoverflow.com/a/18790222/1037948의 확장을 사용 하여 나중에 페이지에서 콘텐츠 (스크립트 또는 HTML 만)를 렌더링합니다. 내부 Queue
는 올바른 주문을 보장해야합니다.
이 기능은 ClientDependency.Core.Mvc.dll에서도 구현됩니다. html 도우미를 제공합니다 : @ Html.RequiresJs 및 @ Html.RenderJsHere (). Nuget 패키지 : ClientDependency-Mvc
새 Layout
페이지를 만들고 콘텐츠 및 라이브러리 섹션 렌더링을 담당하는 전체보기 내에서 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>
이제 , 당신이 렌더링 싶어한다고 가정 About.cshtml
A와 부분보기 아마 AJAX 호출에 응답하여 모달 창으로. 여기서의 목표 _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">×</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에 대한 부분보기에서 기본보기 또는 기본 레이아웃보기로 섹션을 삽입하는 방법"에 대한 자주 묻는 질문에 대한 솔루션이 있습니다. "section + partial"이라는 키워드로 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>
그리고 index.cshtml에는 다음이 있습니다.
@{
ViewBag.Title = "首页";
}
@Html.Partial("head")
<div class="am-container-1">
.......
</div>
@Html.Partial("foot")
그리고 head.cshtml에는 다음과 같은 코드가 있습니다.
@section Head{
<link rel="stylesheet" href="assets/css/amazeui.css" />
<link rel="stylesheet" href="assets/css/style.css" />
}
<header class="header">
......
</header>
@Html.EnsureSection()
foot.cshtml 또는 ad.cshtml에서도 동일합니다. 여전히 Head 또는 Foot 섹션을 정의 할 수 있습니다. 부분보기 파일의 끝에서 @ Html.EnsureSection ()을 한 번 호출해야합니다. asp mvc에서 해당 문제를 제거하기 위해 필요한 모든 것입니다.
다른 사람들이 사용할 수 있도록 내 코드 스 니펫을 공유합니다. 유용하다고 생각되면 주저하지 말고 내 게시물을 평가하십시오. :)
참고 URL : https://stackoverflow.com/questions/5355427/populate-a-razor-section-from-a-partial
'program story' 카테고리의 다른 글
URL 시작 부분의 문자열 제거 (0) | 2020.08.23 |
---|---|
Morgan Logger를 사용하는 방법? (0) | 2020.08.23 |
상위 POM의 프로필에 대해 이미 정의 된 플러그인의 구성을 재정의 할 수 있습니까? (0) | 2020.08.22 |
Android 스튜디오 오류의 의미 : 주석이없는 매개 변수가 @NonNull 매개 변수를 재정의합니다. (0) | 2020.08.22 |
finally 블록에서 예외 발생 (0) | 2020.08.22 |