@ Html.Action в Core Asp.Net

Где @Html.Action в Asp.net Core? Я вижу @Html.ActionLink но не прямой вызов Action, как раньше.

Был ли он заменен на ViewComponents?

Да, ViewComponents – это новый способ сделать это, но они не совсем то же самое, что и @Html.Action чем @Html.Action , хотя … например, в MVC5 и ранее, вызывая «дочерние действия», также выполняли бы любые фильтры (например, если у controllerа были фильтры, украшенные на них), давая им внешний вид как обычные действия … но это не так для ViewComponents, и они выполняются в контексте фактического запроса …

Дополнительная информация о компонентах просмотра: http://www.asp.net/vnext/overview/aspnet-vnext/vc#intro

Обновить: ссылка изменена на

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components

ViewComponents великолепны, но не так хороши для Ajax.

Если вы действительно пропустите метод @ Html.RenderAction, то вот краткая реализация, которую я выбрал для AspNetCore.

 using System; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Routing; namespace Microsoft.AspNetCore.Mvc.Rendering { public static class HtmlHelperViewExtensions { public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, object parameters = null) { var controller = (string)helper.ViewContext.RouteData.Values["controller"]; return RenderAction(helper, action, controller, parameters); } public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, object parameters = null) { var area = (string)helper.ViewContext.RouteData.Values["area"]; return RenderAction(helper, action, controller, area, parameters); } public static IHtmlContent RenderAction(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"); if (area == null) throw new ArgumentNullException("area"); 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 currentHttpContext = helper.ViewContext?.HttpContext; var httpContextFactory = GetServiceOrFail(currentHttpContext); var actionInvokerFactory = GetServiceOrFail(currentHttpContext); var actionSelector = GetServiceOrFail(currentHttpContext); // creating new action invocation context var routeData = new RouteData(); var routeParams = new RouteValueDictionary(parameters ?? new { }); var routeValues = new RouteValueDictionary(new { area = area, controller = controller, action = action }); var newHttpContext = httpContextFactory.Create(currentHttpContext.Features); newHttpContext.Response.Body = new MemoryStream(); foreach (var router in helper.ViewContext.RouteData.Routers) routeData.PushState(router, null, null); routeData.PushState(null, routeValues, null); routeData.PushState(null, routeParams, null); var actionDescriptor = actionSelector.DecisionTree.Select(routeValues).First(); var actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor); // invoke action and retreive the response body var invoker = actionInvokerFactory.CreateInvoker(actionContext); string content = null; await invoker.InvokeAsync().ContinueWith(task => { if (task.IsFaulted) { content = task.Exception.Message; } else if (task.IsCompleted) { newHttpContext.Response.Body.Position = 0; using (var reader = new StreamReader(newHttpContext.Response.Body)) content = reader.ReadToEnd(); } }); return new HtmlString(content); } private static TService GetServiceOrFail(HttpContext httpContext) { if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); var service = httpContext.RequestServices.GetService(typeof(TService)); if (service == null) throw new InvalidOperationException($"Could not locate service: {nameof(TService)}"); return (TService)service; } } } 

Вы можете вызвать из своего представления один из следующих способов:

 @Html.RenderAction("action", "controller", "area", new { id = 1}) @Html.RenderAction("action", "controller", new { id = 1}) @Html.RenderAction("action", new { id = 1}) 

Заметка:

Имя controllerа и, при необходимости, имя области, по умолчанию будут соответствовать соответствующим значениям из ActionContext, если они не указаны.

Для ядра asp.net 2

 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 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.0, и я добавил пару настроек. Есть 2 прославленных статических значения для текущего httpcontext и текущего контекста actioncontext. Тот, который для httpcontext установлен в IHttpContextFactory.Create и я устанавливаю значение для контекста textcontext в коде.

HttpContext – это всего лишь shell вокруг HttpContext.Features , поэтому, если вы что-то меняете в одном, это также изменяется в другом … Я возвращаю то, что я знаю в конце try / catch.

Я удалил IUrlHelper из кеша Items, поскольку это значение будет повторно использоваться, даже если actionContext для сборки urlHelper отличается ( IUrlHelperFactory.GetUrlHelper ).

Asp.net core 2.0 предполагает, что вы этого не сделаете, есть хорошие шансы, что есть другие кешированные вещи, поэтому я рекомендую быть осторожным при использовании этого и просто не делать этого, если вам не нужно.

Для Net Core 2.0

 using Microsoft.AspNetCore.Mvc.Infrastructure; 

замещать

 // var actionSelector = GetServiceOrFail(currentHttpContext); var actionSelector = GetServiceOrFail(currentHttpContext); 

а также

 // var actionDescriptor = actionSelector.DecisionTree.Select(routeValues).First(); var actionDescriptor = actionSelector.ActionDescriptors.Items.Where(i => i.RouteValues["Controller"] == controller && i.RouteValues["Action"] == action).First(); 

Обходное решение от Aries для расширения помощника более не работает для Net Core 2.0, поскольку IActionSelectorDecisionTreeProvider удален из новой версии. См. Ссылку ниже.

https://github.com/Microsoft/aspnet-api-versioning/issues/154

Я использовал коды людей на этой странице, чтобы получить правильный результат.

https://stackoverflow.com/a/39951006/6778726

https://stackoverflow.com/a/46859170/6778726

Например, в старом classе при выполнении следующего кода отображается ошибка

 @Html.RenderAction("About", "Home") 

Исправлен следующий код :

 using System; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Routing; namespace Microsoft.AspNetCore.Mvc.Rendering { public static class HtmlHelperViewExtensions { public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, object parameters = null) { var controller = (string)helper.ViewContext.RouteData.Values["controller"]; return RenderAction(helper, action, controller, parameters); } public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, object parameters = null) { var area = (string)helper.ViewContext.RouteData.Values["area"]; return RenderAction(helper, action, controller, area, parameters); } public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, string area, object parameters = null) { if (action == null) throw new ArgumentNullException(nameof(controller)); if (controller == null) throw new ArgumentNullException(nameof(action)); 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 currentHttpContext = helper.ViewContext.HttpContext; var httpContextFactory = GetServiceOrFail(currentHttpContext); var actionInvokerFactory = GetServiceOrFail(currentHttpContext); var actionSelector = GetServiceOrFail(currentHttpContext); // creating new action invocation context var routeData = new RouteData(); var routeParams = new RouteValueDictionary(parameters ?? new { }); var routeValues = new RouteValueDictionary(new { area, controller, action }); var newHttpContext = httpContextFactory.Create(currentHttpContext.Features); newHttpContext.Response.Body = new MemoryStream(); foreach (var router in helper.ViewContext.RouteData.Routers) routeData.PushState(router, null, null); routeData.PushState(null, routeValues, null); routeData.PushState(null, routeParams, null); var actionDescriptor = actionSelector.ActionDescriptors.Items.First(i => i.RouteValues["Controller"] == controller && i.RouteValues["Action"] == action); var actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor); // invoke action and retreive the response body var invoker = actionInvokerFactory.CreateInvoker(actionContext); string content = null; await invoker.InvokeAsync().ContinueWith(task => { if (task.IsFaulted) { content = task.Exception.Message; } else if (task.IsCompleted) { newHttpContext.Response.Body.Position = 0; using (var reader = new StreamReader(newHttpContext.Response.Body)) content = reader.ReadToEnd(); } }); return new HtmlString(content); } private static TService GetServiceOrFail(HttpContext httpContext) { if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); var service = httpContext.RequestServices.GetService(typeof(TService)); if (service == null) throw new InvalidOperationException($"Could not locate service: {nameof(TService)}"); return (TService)service; } } } 

Следующие примеры были успешно протестированы:

 @Html.RenderAction("About") @Html.RenderAction("About", "Home") @Html.RenderAction("About", new { data1 = "test1", data2 = "test2" }) @Html.RenderAction("About", "Home", new { data1 = "test1", data2 = "test2" }) 
  • MVC Razor видит, что Intellisense сломан в VS 2013/2015/2017
  • Обслуживание favicon.ico в ASP.NET MVC
  • Авторизовать атрибут и jquery AJAX в asp.net MVC
  • ASP MVC в IIS 7 приводит к: Ошибка HTTP 403.14 - Запрещено
  • Проверка MVC3 - требуется от группы
  • Модель, поддерживающая контекст «ApplicationDbContext», изменилась с момента создания базы данных
  • Как RequireJS работает с несколькими страницами и частичными представлениями?
  • Форма MVC не может отправлять список объектов
  • ASP.NET MVC - привязка объекта типа «MODELNAME» не удалась, поскольку другой объект того же типа уже имеет такое же значение первичного ключа
  • Отправьте данные JSON через POST (ajax) и получите ответ json от Controller (MVC)
  • Использование инъекции зависимостей без какой-либо библиотеки DI
  • Давайте будем гением компьютера.