asp.net-core – 如何将在TagHelper流程方法中生成的脚本渲染到
我在TagHelper类的进程方法中生成脚本如下
[TargetElement("MyTag")] public Class MYClass: TagHelper{ public override void Process(TagHelperContext context,TagHelperOutput output) { StringBuilder builder = new StringBuilder(); builder.Append("<script>"); builder.Append("//some javascript codes here); builder.Append("</script>"); output.Content.Append(builder.ToString()); } } 现在它将脚本放在标签元素旁边作为其兄弟. 我需要将脚本放在body部分的末尾. 解决方法
我创建了一对能够解决问题的自定义标记帮助程序.
第一个是< storecontent>它只是将包含在其中的html内容存储在TempData字典中.它不提供直接输出.内容可以是内联脚本或任何其他html.许多这种标签帮助器可以放置在不同的位置,例如在部分视图中. 第二个标签助手是< renderstoredcontent>并且它将所有先前存储的内容呈现在期望的位置,例如在主体元素的末尾. StoreContentTagHelper.cs的代码: using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Razor.Runtime.TagHelpers; namespace YourProjectHere.TagHelpers { [TargetElement("storecontent",Attributes = KeyAttributeName)] public class StoreContentTagHelper : TagHelper { private const string KeyAttributeName = "asp-key"; private const string _storageKey = "storecontent"; private const string _defaultListKey = "DefaultKey"; [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } [HtmlAttributeName(KeyAttributeName)] public string Key { get; set; } public override async Task ProcessAsync(TagHelperContext context,TagHelperOutput output) { output.SuppressOutput(); TagHelperContent childContent = await context.GetChildContentAsync(); var storageProvider = ViewContext.TempData; Dictionary<string,List<HtmlString>> storage; List<HtmlString> defaultList; if (!storageProvider.ContainsKey(_storageKey) || !(storageProvider[_storageKey] is Dictionary<string,List<HtmlString>>)) { storage = new Dictionary<string,List<HtmlString>>(); storageProvider[_storageKey] = storage; defaultList = new List<HtmlString>(); storage.Add(_defaultListKey,defaultList); } else { storage = ViewContext.TempData[_storageKey] as Dictionary<string,List<HtmlString>>; if (storage.ContainsKey(_defaultListKey)) { defaultList = storage[_defaultListKey]; } else { defaultList = new List<HtmlString>(); storage.Add(_defaultListKey,defaultList); } } if (String.IsNullOrEmpty(Key)) { defaultList.Add(new HtmlString(childContent.GetContent())); } else { if(storage.ContainsKey(Key)) { storage[Key].Add(new HtmlString(childContent.GetContent())); } else { storage.Add(Key,new List<HtmlString>() { new HtmlString(childContent.GetContent()) }); } } } } } RenderStoredContentTagHelper.cs的代码: using System; using System.Linq; using System.Collections.Generic; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Razor.Runtime.TagHelpers; namespace YourProjectHere.TagHelpers { [TargetElement("renderstoredcontent",Attributes = KeyAttributeName)] public class RenderStoredContentTagHelper : TagHelper { private const string KeyAttributeName = "asp-key"; private const string _storageKey = "storecontent"; [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } [HtmlAttributeName(KeyAttributeName)] public string Key { get; set; } public override void Process(TagHelperContext context,TagHelperOutput output) { output.TagName = String.Empty; var storageProvider = ViewContext.TempData; Dictionary<string,List<HtmlString>> storage; if (!storageProvider.ContainsKey(_storageKey) || !(storageProvider[_storageKey] is Dictionary<string,List<HtmlString>>)) { return; } storage = storageProvider[_storageKey] as Dictionary<string,List<HtmlString>>; string html = ""; if (String.IsNullOrEmpty(Key)) { html = String.Join("",storage.Values.SelectMany(x => x).ToList()); } else { if (!storage.ContainsKey(Key)) return; html = String.Join("",storage[Key]); } TagBuilder tagBuilder = new TagBuilder("dummy"); tagBuilder.InnerHtml = html; output.Content.SetContent(tagBuilder.InnerHtml); } } } 基本用法: 在某些视图或部分视图中: <storecontent asp-key=""> <script> your inline script... </script> </storecontent> 在另一个位置: <storecontent asp-key=""> <script src="..."></script> </storecontent> 最后在应该呈现两个脚本的所需位置: <renderstoredcontent asp-key=""></renderstoredcontent> 而已. 几点说明: >可以有任意数量的< storecontent>标签. asp-key属性是必需的,至少为空“”.如果为此属性指定特定值,则可以对存储的内容进行分组,并在不同位置呈现特定组.例如.如果您使用asp-key =“scripts”指定某些内容,而使用asp-key =“footnotes”指定其他内容,那么您可以使用以下方式仅将第一个组渲染为某个位置: < renderstoredcontent asp-key =“scripts”>< / renderstoredcontent> 另一组“脚注”可以在另一个位置呈现. >< storecontent>必须在< renderstoredcontent>之前定义被申请;被应用.在ASP.NET中,响应以反向层次顺序生成,首先生成最内部的部分视图,然后是父部分视图,然后是主视图,最后是布局页面.因此,您可以轻松地使用这些标记帮助程序在局部视图中定义脚本,然后在布局页面的正文部分末尾呈现脚本. 对不起,很长的帖子,我希望它有所帮助! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – ASP.NET MVC 5 Html.HiddenFor呈现不正确的
- razor – 没有布局参考的ASP.NET默认MVC4应用程序内容页面?
- asp.net-mvc – 在ASP.NET MVC中,response.redirect如何工作
- asp.net-mvc – ASP.NET MVC与Zeitgeist
- 深度探秘.NET 5.0
- asp.net-mvc – 如何使用OutputCacheProfiles来压缩标头Var
- asp.net – 如何在MVC 3中设置图表系列颜色?
- 为什么在ASP.NET中刷新页面时会执行按钮单击事件?
- 简明的ASP.NET验证摘要
- asp.net – Quartz.net和Ninject:如何使用NInject将实现绑
- asp.net – 无法使用PreSendRequestHeaders()覆盖
- asp.net-core – 在Visual Studio 2015 for ASP.
- asp.net – ScriptManager.axd不会缓存
- 如何将asp.net的后台cs代码移动到页面上
- asp.net-mvc – ASP.NET MVC – 如何访问除Contr
- 如何将ASP.NET用户控件转换为Web /复合控件?
- asp.net-mvc – 产品目录搜索 – NoSQL / MongoD
- kendo-ui – Kendo Grid的水平滚动
- asp.net-mvc – 如何将特定于HTTP-Request的对象
- asp.net – 将RSS pubDate格式化为.NET DateTime