mvc4 @html.action,asp.net core mvc @Html.Action

1、创建 静态类 HtmlHelperViewExtensions,其命名空间为  Microsoft.AspNetCore.Mvc.Rendering。这样我们直接用@Html直接可以 使用Action方法了。{

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 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();            var httpContextAccessor = helper.ViewContext.HttpContext.RequestServices.GetRequiredService();            var actionSelector = serviceProvider.GetRequiredService();

// 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().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().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

services.AddSingleton();

(备注:因为net core 默认不将IHttpContextAccessor,IActionContextAccessor 依赖注入,所以需要手动进行依赖注入)

3、在页面中,我们就可以直接用 @Html.Action()方法 直接请求 控制器的方法了。

作者:大坤儿

链接:https://www.jianshu.com/p/f44a19960549

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值