OWIN отправляет статический файл для нескольких маршрутов
Я делаю SPA, который находится поверх ASP.Net WebAPI. Я ожидаю использовать историю HTML5, а не #/
для маршрутизации истории, но это создает проблему для глубокой привязки, мне нужно убедиться, что /
и /foo/bar
все возвращают один и тот же файл HTML (и мой JS будет отображать правая часть СПА).
Как получить OWIN/Katana для возврата одного и того же файла HTML для нескольких разных URL-адресов?
Ответы
Ответ 1
Чтобы сделать вещи простыми, сохраняя при этом все преимущества кеширования и т.д. из промежуточного программного обеспечения StaticFiles, я просто переписал путь запроса, используя встроенное промежуточное ПО, например
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Map("/app", spa =>
{
spa.Use((context, next) =>
{
context.Request.Path = new PathString("/index.html");
return next();
});
spa.UseStaticFiles();
});
app.UseWelcomePage();
}
}
Это будет страница приветствия ничем, кроме /app/*
, которая будет всегда служить index.html вместо этого.
Ответ 2
Я столкнулся с аналогичной проблемой, используя Angular js, и использовал несколько иной подход для решения проблемы.
Мы использовали Owin для сопоставления маршрута к точке входа SPA (index.html). Это позволяет вам получить доступ к SPA и перейти на разные страницы. Однако, если вы когда-либо обновили страницу, вы получили бы 404. По сути, маршрутизация AngularJS и маршрутизация Owin/Katana наступали друг на друга.
Я решил проблему, создав пользовательский DelegatingHandler. Этот обработчик делегирования используется всякий раз, когда Owin/Katana не может найти маршрут, соответствующий запросу (404).
public class CustomDelegatingHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Task<HttpResponseMessage> response = base.SendAsync(request, cancellationToken);
if (response.Result.StatusCode == HttpStatusCode.NotFound)
{
response.Result.Content = new StringContent(File.ReadAllText(@"index.html"));
response.Result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
response.Result.StatusCode = HttpStatusCode.OK;
}
return response;
}
}
Фрагмент выше возвращает index.html, точку входа SPA, когда мы не можем найти страницу, соответствующую запросу.
Чтобы использовать этот обработчик делегирования, вы должны добавить следующую строку в свой HttpConfiguration() при запуске хоста Owin:
var httpConfig = new HttpConfiguration();
httpConfig.MessageHandlers.Add(new CustomDelegatingHandler());
Короче говоря, у меня есть маршрут по умолчанию, который отображается в SPA, и любой непризнанный маршрут будет проходить через DelegatingHandler и обслуживать тот же SPA. Мы не модифицируем Request.Path, позволяя SPA направить запрос на нужную страницу.