分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

Asp.Net Core 之 @Html.Action 迁移

发布时间:2023-09-06 02:02责任编辑:董明明关键词:暂无标签

想必只要 接触了 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

Asp.Net Core 之 @Html.Action 迁移

原文地址:https://www.cnblogs.com/GavinSun/p/9244833.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved