想必只要 接触了 net core的小伙伴们 已经发现 @html.Action()方法 官方已经不提供支持了,转而使用 ViewComponents替代了,同时也增加了TagHelper。但是 如果想用以前的@Html.Action()方法,我们其实可以自己动手去实现它。
下面就开始 实现之旅吧!
1、创建 静态类 HtmlHelperViewExtensions,其命名空间为 Microsoft.AspNetCore.Mvc.Rendering。这样我们直接用@Html直接可以 使用Action方法了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
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
标签:Core,Asp,helper,action,controller,Html,var,new,null From: https://www.cnblogs.com/Alex80/p/17621891.html