gpt4 book ai didi

c# - ASP.Net 核心 2.0 : Creating UrlHelper without request

转载 作者:IT王子 更新时间:2023-10-29 04:22:15 28 4
gpt4 key购买 nike

我正在为后台工作人员创建一个 UrlHelper 来创建回调 url,这意味着它不是正常请求的一部分,我只能通过 DI 请求它。

在 ASP.Net 5 中,我可以只创建一个 HttpRequest 并为其提供与构建我的应用程序时相同的 HttpConfiguration,但在 ASP.Net Core 2.0 中,UrlHelper 依赖于一个完整的 ActionContext,这有点难以制作。

我有一个工作原型(prototype),但它使用了一种令人讨厌的黑客手段将路由数据从应用程序启动过程中偷运出去。有更好的方法吗?

public class Capture
{
public IRouter Router { get; set; }
}

public static class Ext
{
// Step 1: Inject smuggler when building web host
public static IWebHostBuilder SniffRouteData(this IWebHostBuilder builder)
{
return builder.ConfigureServices(svc => svc.AddSingleton<Capture>());
}

// Step 2: Swipe the route data in application startup
public static IApplicationBuilder UseMvcAndSniffRoutes(this IApplicationBuilder app)
{
var capture = app.ApplicationServices.GetRequiredService<Capture>();
IRouteBuilder capturedRoutes = null;
app.UseMvc(routeBuilder => capturedRoutes = routeBuilder);
capture.Router = capturedRoutes?.Build();
return app;
}

// Step 3: Build the UrlHelper using the captured routes and webhost
public static IUrlHelper GetStaticUrlHelper(this IWebHost host, string baseUri)
=> GetStaticUrlHelper(host, new Uri(baseUri));
public static IUrlHelper GetStaticUrlHelper(this IWebHost host, Uri baseUri)
{
HttpContext httpContext = new DefaultHttpContext()
{
RequestServices = host.Services,
Request =
{
Scheme = baseUri.Scheme,
Host = HostString.FromUriComponent(baseUri),
PathBase = PathString.FromUriComponent(baseUri),
},
};

var captured = host.Services.GetRequiredService<Capture>();
var actionContext = new ActionContext
{
HttpContext = httpContext,
RouteData = new RouteData { Routers = { captured.Router }},
ActionDescriptor = new ActionDescriptor(),
};
return new UrlHelper(actionContext);
}
}

// Based on dotnet new webapi

public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args);//.Run();
}

public static IWebHost BuildWebHost(string[] args)
{
var captured = new Capture();
var webhost = WebHost.CreateDefaultBuilder(args)
.SniffRouteData()
.UseStartup<Startup>()
.Build();

var urlHelper = webhost.GetStaticUrlHelper("https://my.internal.service:48923/somepath");
Console.WriteLine("YO! " + urlHelper.Link(nameof(ValuesController), null));
return webhost;
}
}

public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, Capture capture)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseMvcAndSniffRoutes();
}
}

[Route("api/[controller]", Name = nameof(ValuesController))]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}

// etc
}

最佳答案

浏览源代码似乎有不少 hacky 解决方案。

在 UseMvc() 方法中,正在构建的 IRouter 对象是 passed to the RouterMiddleware ,这stores it in a private field并将其仅暴露给请求。因此,反射(reflection)将是您唯一的其他选择,而这显然是行不通的。

但是,如果您只需要使用 IUrlHelper.Content() 生成静态路径,则不需要路由器作为 default implementation won't use it .在这种情况下,您可以像这样创建助手:

var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var urlHelper = new UrlHelper(actionContext);

关于c# - ASP.Net 核心 2.0 : Creating UrlHelper without request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46096068/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com