バックグラウンドワーカーのコールバックURLを作成するためのUrlHelperを作成しています。つまり、通常のリクエストの一部ではないため、DI経由でリクエストできます。ASP.Net Core 2.0:リクエストなしでUrlHelperを作成する
私はちょうどHttpRequestを作成し、私は自分のアプリケーションを構築するために使用したものと同じHttpConfigurationを与えることができますが、ASP.Net Core 2.0ではUrlHelperは、少し難しい完全なActionContextに依存します。
私は実用的なプロトタイプを持っていますが、アプリケーション起動プロセスからルートデータを密かに盗み取るために厄介なハックを使用しています。これを行うより良い方法はありますか?
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
}
をこれはひどいアイデアかもしれませんが、あなたがバックグラウンドスレッドからそれを引き続き使用することができますので、あなただけの*リクエストの間に作成された*のUrlHelperを保存することはできませんか?だから、最初のリクエストが行われた後*あなたはそのスレッドを開始しますか? – poke
これをチェックする機会がありましたか? https://stackoverflow.com/questions/37322076/injection-of-iurlhelper-in-asp-net-core-1-0-rc2 –
@poke、それはおそらく動作するだろうが、明らかな欠点があるので、それを最後の手段として使用してください。 – Stylpe