限り接触はネットコア少し友人が@ html.Action()メソッドは、もはやの賛成で公式サポートを提供して認められません持っている必要がありますようViewComponentsもTagHelperを高めながら、置き換え。あなたは以前、@ Html.Action()メソッドを使用したい場合はしかし、我々は実際にそれを達成するためにそれを自分で行うことができます。
以下は、旅を実現するために始めました!
1、静的クラスHtmlHelperViewExtensionsを作成し、その名前空間はMicrosoft.AspNetCore.Mvc.Renderingです。だから我々は直接@htmlとアクションの直接法を使用することができます。
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に示すように、 ConfigureServices方法スタートアップを添加しました。
services.AddSingleton <IHttpContextAccessor、HttpContextAccessor()。
services.AddSingleton <IActionContextAccessor、ActionContextAccessor>();
(注:ネットコアは、デフォルトではありませんのでIHttpContextAccessor、IActionContextAccessorの依存性注入を、それが手動で依存性注入する必要があります)
3は、ページ内に、我々は直接@ Html.Action()メソッド直接法・コントローラは、要求することができます。
4.まとめ:今日、Microsoft関係者は、代わりに新しいTagHelper、Viewコンポーネントの前に書かれて提供してきました。このチュートリアルでは、使用にもう少しのパートナーになることを望んでいないだけで、ビュー層を対象としています。それは、新しいプロジェクトである、またはの使用をお勧めします場合は Viewコンポーネントを!