asp.net mvc4 html.action,[ASP.NET Core]ASP.NET Core应用程序开发中如何使用@Html.Action?

问题描述

在ASP.NET MVC的应用程序开发中,Razor视图页面可以使用@Html.Action扩展方法可渲染页面,但在ASP.NET Core的Razor视图页面中没有了@Html.Action这个扩展方法了,而是ViewComponents组件。那么,在ASP.NET Core应用程序开发中是否不可用@Html.Action扩展了呢?

方案一

在ASP.NET Core中微软官方的确没有实现@Html.Action这个扩展方法了,取而代之的是ViewComponents组件,而且ViewComponents组件的功能也非常强大,但对Ajax的支持不是太好。

如果你仍然想在ASP.NET Core中使用@Html.Action,可以自己实现@Html.Action扩展方法,如:

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)

{

var currentHttpContext = helper.ViewContext?.HttpContext;

var httpContextFactory = GetServiceOrFail(currentHttpContext);

var actionInvokerFactory = GetServiceOrFail(currentHttpContext);

var actionSelector = GetServiceOrFail(currentHttpContext);

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);

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;

}

}

}

在Razor视图页面中的使用示例如:

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

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

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

方案二

其中IHtmlHelper的@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 RenderActionAsync(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)

{

var serviceProvider = helper.ViewContext.HttpContext.RequestServices;

var actionContextAccessor = helper.ViewContext.HttpContext.RequestServices.GetRequiredService();

var httpContextAccessor = helper.ViewContext.HttpContext.RequestServices.GetRequiredService();

var actionSelector = serviceProvider.GetRequiredService();

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);

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));

}

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET MVC ,在 `Program.cs` 文件并不直接处理控制器的字符, 它主要负责启动.NET Core 应用程序在 `Program.cs` 你可以使用以下代码来设置和启动 ASP.NET Core 应用程序: ```csharp using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } ``` 在上面的代码,我们使用 `CreateDefaultBuilder` 方法创建一个默认的 `IHostBuilder` 实例,并使用 `ConfigureWebHostDefaults` 方法配置 Web 主机。在 `webBuilder.UseStartup<Startup>()` ,我们指定了 `Startup` 类作为应用程序的启动配置类。 控制器的字符输出是通过处理 HTTP 请求来实现的,因此你需要在 `Startup.cs` 文件配置路由和控制器。在 `Startup.cs` 的 `ConfigureServices` 方法,你可以添加控制器服务: ```csharp public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); } ``` 然后,在 `Startup.cs` 的 `Configure` 方法配置路由: ```csharp public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); // ... } ``` 上述代码,我们使用 `app.UseEndpoints` 方法配置了默认路由,并将请求路由到对应的控制器和动作方法。 这样,在运行 ASP.NET MVC 应用程序后,当你访问相应的控制器和动作方法时,网页将会显示控制器的字符输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值