我添加了一个自定义markdown taghelper,但是它不显示内容。我尝试使用不同的调整,但是以某种方式都无法解决问题。我真的不知道我做错了什么,或者缺少的部分是什么?
我希望有人会仔细检查我的代码并帮助我解决此问题,代码如下:-
namespace Web.TagHelpers
{
[HtmlTargetElement("markdown")]
public class MarkdownTagHelper : TagHelper
{
[HtmlAttributeName("markdown")]
public ModelExpression Markdown { get; set; }
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
await base.ProcessAsync(context, output);
var markdown = Markdown?.Model?.ToString() ?? "";
var content = ConvertToMarkDown(markdown);
output.TagName = null;
output.Content.SetHtmlContent(content);
}
private string ConvertToMarkDown(string markdown)
{
var sanitizer = new HtmlSanitizer();
sanitizer.RemovingAttribute += OnRemovingAttribute;
sanitizer.AllowedTags.Remove("form");
sanitizer.AllowedTags.Remove("button");
sanitizer.AllowedTags.Remove("input");
// parse the markdown to HTML
markdown = Westwind.AspNetCore.Markdown.Markdown.Parse(markdown);
// encode any custom tags (pasting e-mails and other markup (XML))
// From author of HtmlSanitizer
// https://gist.github.com/mganss/00bec2c2245c0ef86d9c82d6211def7b
markdown = HtmlRegex.Replace(markdown, m =>
{
var tagName = m.Groups[1].Value;
if (!HtmlTags.Contains(tagName))
return "<" + m.Value.Substring(1);
return m.Value;
});
markdown = sanitizer.Sanitize(markdown);
return markdown;
}
private void OnRemovingAttribute(object sender, RemovingAttributeEventArgs e)
{
if (!e.Attribute.Value.Contains("vbscript:", StringComparison.CurrentCultureIgnoreCase)
&& !e.Attribute.Value.Contains("javascript:", StringComparison.CurrentCultureIgnoreCase)
&& !e.Attribute.Value.Contains("data:", StringComparison.CurrentCultureIgnoreCase)
&& !e.Attribute.Name.StartsWith("on", StringComparison.CurrentCultureIgnoreCase))
{
// don't remove the attribute if we've deemed it safe
e.Cancel = true;
}
}
static Regex HtmlRegex = new Regex(@"</?([a-z]+[1-6]?)", RegexOptions.IgnoreCase);
static HashSet<string> HtmlTags = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "bdi", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "command", "datalist", "dd", "del", "details", "dfn", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "img", "input", "ins", "isindex", "kbd", "keygen", "label", "legend", "li", "link", "map", "mark", "menu", "meta", "meter", "nav", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "pre", "progress", "q", "rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr" };
}
我有以下剃须刀页面来显示内容:
@model IEnumerable<Post>
@{
ViewData["Title"] = "My Posts";
}
<p class="heading">Recent Technology Posts</p>
<div class="container-post">
<div class="row">
@foreach (var p in Model)
{
<div class="col-md-6 container-column">
<div class="item-group">
<div class="item one">
<a href="@Url.Action("GetPostBySlug", "Post", new {slug = p.Slug })">@p.Topic</a>
</div>
<div class="item two">
<p class="fa fa-thumb-tack"></p><span>Posted On:</span>
<i class="fa fa-calendar"></i>
<i class="timeStampValue" data-value="@p.Published"></i>
<i class="fa fa-user"></i><span>Post By: Author Name</span>
</div>
<hr />
<div class="item three">
<markdown markdown="@p.Content" />
</div>
<div class="readMore">
<span class="btn btn-outline-primary">ReadMore..</span>
</div>
</div>
</div>
}
</div>
</div>
启动类:-
namespace Web
{
public class Startup
{
private IConfiguration Config { get; }
public Startup(IConfiguration configuration)
{
Config = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureDatabase(Config);
services.AddScoped(typeof(IAsyncRepository<>), typeof(PostRepository<>));
services.AddMvc();
services.AddHttpContextAccessor();
services.AddMarkdown();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, PostContext context)
{
context.Database.EnsureCreated();
app.UseHttpsRedirection();
app.UseMarkdown();
app.UseStaticFiles();
app.UseRouting(env);
}
}
_ViewImports文件:
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, NWebsec.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Web
控制器:-
public async Task<IActionResult> GetAllPosts()
{
var result = await _repository.GetAllPosts();
return View(result);
}