mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-19 04:18:16 +08:00
实现加载md文档内容
This commit is contained in:
@ -0,0 +1,101 @@
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
|
||||
namespace FreeSql.Site.UI.Common
|
||||
{
|
||||
public static class HtmlHelperViewExtensions
|
||||
{
|
||||
public static IHtmlContent Action(this IHtmlHelper helper, string action, object parameters = null)
|
||||
{
|
||||
var controller = (string)helper.ViewContext.RouteData.Values["controller"];
|
||||
|
||||
return Action(helper, action, controller, parameters);
|
||||
}
|
||||
|
||||
public static IHtmlContent Action(this IHtmlHelper helper, string action, string controller, object parameters = null)
|
||||
{
|
||||
var area = (string)helper.ViewContext.RouteData.Values["area"];
|
||||
|
||||
return Action(helper, action, controller, area, parameters);
|
||||
}
|
||||
|
||||
public static IHtmlContent Action(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
|
||||
{
|
||||
if (action == null)
|
||||
throw new ArgumentNullException("action");
|
||||
|
||||
if (controller == null)
|
||||
throw new ArgumentNullException("controller");
|
||||
|
||||
|
||||
var task = RenderActionAsync(helper, action, controller, area, parameters);
|
||||
|
||||
return task.Result;
|
||||
}
|
||||
|
||||
private static async Task<IHtmlContent> RenderActionAsync(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
|
||||
{
|
||||
// fetching required services for invocation
|
||||
var serviceProvider = helper.ViewContext.HttpContext.RequestServices;
|
||||
var actionContextAccessor = helper.ViewContext.HttpContext.RequestServices.GetRequiredService<IActionContextAccessor>();
|
||||
var httpContextAccessor = helper.ViewContext.HttpContext.RequestServices.GetRequiredService<IHttpContextAccessor>();
|
||||
var actionSelector = serviceProvider.GetRequiredService<IActionSelector>();
|
||||
|
||||
// creating new action invocation context
|
||||
var routeData = new RouteData();
|
||||
foreach (var router in helper.ViewContext.RouteData.Routers)
|
||||
{
|
||||
routeData.PushState(router, null, null);
|
||||
}
|
||||
routeData.PushState(null, new RouteValueDictionary(new { controller = controller, action = action, area = area }), null);
|
||||
routeData.PushState(null, new RouteValueDictionary(parameters ?? new { }), null);
|
||||
|
||||
//get the actiondescriptor
|
||||
RouteContext routeContext = new RouteContext(helper.ViewContext.HttpContext) { RouteData = routeData };
|
||||
var candidates = actionSelector.SelectCandidates(routeContext);
|
||||
var actionDescriptor = actionSelector.SelectBestCandidate(routeContext, candidates);
|
||||
|
||||
var originalActionContext = actionContextAccessor.ActionContext;
|
||||
var originalhttpContext = httpContextAccessor.HttpContext;
|
||||
try
|
||||
{
|
||||
var newHttpContext = serviceProvider.GetRequiredService<IHttpContextFactory>().Create(helper.ViewContext.HttpContext.Features);
|
||||
if (newHttpContext.Items.ContainsKey(typeof(IUrlHelper)))
|
||||
{
|
||||
newHttpContext.Items.Remove(typeof(IUrlHelper));
|
||||
}
|
||||
newHttpContext.Response.Body = new MemoryStream();
|
||||
var actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor);
|
||||
actionContextAccessor.ActionContext = actionContext;
|
||||
var invoker = serviceProvider.GetRequiredService<IActionInvokerFactory>().CreateInvoker(actionContext);
|
||||
await invoker.InvokeAsync();
|
||||
newHttpContext.Response.Body.Position = 0;
|
||||
using (var reader = new StreamReader(newHttpContext.Response.Body))
|
||||
{
|
||||
return new HtmlString(reader.ReadToEnd());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new HtmlString(ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
actionContextAccessor.ActionContext = originalActionContext;
|
||||
httpContextAccessor.HttpContext = originalhttpContext;
|
||||
if (helper.ViewContext.HttpContext.Items.ContainsKey(typeof(IUrlHelper)))
|
||||
{
|
||||
helper.ViewContext.HttpContext.Items.Remove(typeof(IUrlHelper));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
Examples/website/FreeSql.Site.UI/Common/MarkdownTagHelper.cs
Normal file
40
Examples/website/FreeSql.Site.UI/Common/MarkdownTagHelper.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using CommonMark;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql.Site.UI.Common.TagHelpers
|
||||
{
|
||||
[HtmlTargetElement("markdown", TagStructure = TagStructure.NormalOrSelfClosing)]
|
||||
[HtmlTargetElement(Attributes = "markdown")]
|
||||
public class MarkdownTagHelper : TagHelper
|
||||
{
|
||||
public MarkdownTagHelper()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ModelExpression Content { get; set; }
|
||||
|
||||
public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
if (output.TagName == "markdown")
|
||||
{
|
||||
output.TagName = null;
|
||||
}
|
||||
output.Attributes.RemoveAll("markdown");
|
||||
var content = await GetContent(output);
|
||||
var markdown = WebUtility.HtmlEncode(WebUtility.HtmlDecode(content));
|
||||
var html = CommonMarkConverter.Convert(markdown);
|
||||
output.Content.SetHtmlContent(html ?? "");
|
||||
}
|
||||
|
||||
private async Task<string> GetContent(TagHelperOutput output)
|
||||
{
|
||||
if (Content == null)
|
||||
return (await output.GetChildContentAsync()).GetContent();
|
||||
return Content.Model?.ToString();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user