Построение URL-адресов MVC в IApplicationLifetime.ApplicationStarted
событийном повторении разных вещей всегда заканчивалось исключениями. Например
public void ConfigureServices(IServiceCollection services) {
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLife, IServiceProvider serviceProvider) {
appLife.ApplicationStarted.Register(() => {
var helperFactory = serviceProvider.GetService<IUrlHelperFactory>();
var ctx = serviceProvider.GetService<IActionContextAccessor>();
});
}
System.ObjectDisposedException: «Невозможно получить доступ к удаленному объекту.»
IActionContextAccessor
, похоже, проблема: поскольку мы не находимся в HTTP-запросе, ActionContext
не доступен. При непосредственном введении IActionContextAccessor
в Configure
я получил объект. Но это свойство ActionContext
равно нулю, которое потребуется для конструктора UrlHelper
:
var helper = new UrlHelper(actionContext.ActionContext);
Поскольку из этого контекста требовалась только информация о маршрутизации, я попытался создать некий фальшивый контекст с моими маршрутами
IRouter localRoutes;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLife, IServiceProvider serviceProvider) {
appLife.ApplicationStarted.Register(() => {
var routeData = new RouteData();
routeData.PushState(localRoutes, new RouteValueDictionary(), new RouteValueDictionary());
var urlHelperFactory = app.ApplicationServices.GetRequiredService<IUrlHelperFactory>();
IUrlHelper helper = urlHelperFactory.GetUrlHelper(
new ActionContext(
new DefaultHttpContext(),
routeData,
new ActionDescriptor() { })
);
string url = helper.Action("Index", "Home");
});
app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Dashboard}/{action=Index}/{id?}");
localRoutes = routes.Build();
});
}
При вызове helper.Action
генерируется исключение:
System.ArgumentNullException: «Значение не может быть нулевым.»
Не знаю, как это исправить. Я не хочу создавать URL-адреса вручную, так как изменения должны применяться в нескольких местах.
Фон: прогрев приложения
Моему приложению ASP.NET Core 2 требуется несколько секунд для обработки первого запроса после запуска, где следующие запросы выполняются довольно быстро. Поскольку это неприемлемо для пользовательского опыта, я хочу прогреть свое приложение.
В старом стеке IIS 4.x есть preloadEnabled , именно то, что мне нужно:
Указывает, что IIS имитирует запрос пользователя к странице приложения или виртуального каталога по умолчанию для его инициализации. [...]
К сожалению, похоже, что нет такой опции для нового веб-сервера Kestrel, который также может работать в Linux. Поэтому я бы хотел реализовать что-то подобное самостоятельно, сделав 2-3 запроса.