在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
想必只要 接触了 net core的小伙伴们 已经发现 @html.Action()方法 官方已经不提供支持了,转而使用 ViewComponents替代了,同时也增加了TagHelper。但是 如果想用以前的@Html.Action()方法,我们其实可以自己动手去实现它。 下面就开始 实现之旅吧! 1、创建 静态类 HtmlHelperViewExtensions,其命名空间为 Microsoft.AspNetCore.Mvc.Rendering。这样我们直接用@Html直接可以 使用Action方法了。
using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using System; using System.IO; using System.Threading.Tasks; namespace Microsoft.AspNetCore.Mvc.Rendering { 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)); } } } } }
2、 在Startup中的 ConfigureServices 方法添加: services.AddSingleton<IHttpContextAccessor, HttpContextAccessor(); services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); (备注:因为net core 默认不将IHttpContextAccessor,IActionContextAccessor 依赖注入,所以需要手动进行依赖注入) 3、在页面中,我们就可以直接用 @Html.Action()方法 直接请求 控制器的方法了。 4、小结:如今微软官方已经提供了 新的 TagHelper、View components 来替代之前的写法。这个教程只适用于对视图层不想做更变的小伙伴使用。如果 是新项目的,还是建议使用 View components! 转自:https://blog.csdn.net/huanghuangtongxue/article/details/78987833
|
请发表评论