Как перехватить 404 с помощью связующего ПО Owin

Фон

Сначала позвольте мне объяснить фон. Я работаю над проектом, который пытается объединить внутренний сервер, использующий Web API, настроенный через OWIN, размещенный в IIS, но, возможно, в будущем другие поддерживаемые OWIN хосты, с внешним интерфейсом, использующим AngularJS.

Интерфейс AngularJS полностью статичен. Я полностью избегаю серверных технологий, таких как MVC / Razor, WebForms, Bundles, всего, что связано с внешним интерфейсом и активами, которые он использует, и вместо этого использую новейшие и лучшие методы с использованием Node.js, Grunt / Gulp и т. Д. ... для обработки CSS-компиляции, связывания, минимизации и т. д. По причинам, которые я здесь не буду обсуждать, я храню проекты внешнего интерфейса и сервера в разных местах в рамках одного проекта (а не вставляю их все в проект Host напрямую (см. «сырой»). диаграмма ниже).

MyProject.sln
server
  MyProject.Host
     MyProject.Host.csproj
     Startup.cs
     (etc.)
frontend
  MyProjectApp
     app.js
     index.html
     MyProjectApp.njproj
     (etc.)

Итак, что касается внешнего интерфейса, все, что мне нужно сделать, - это заставить мой хост обслуживать мой статический контент. В Express.js это тривиально. С OWIN я смог сделать это легко, используяMicrosoft.Owin.StaticFiles промежуточное программное обеспечение, и оно прекрасно работает (это очень гладко).

Вот мойOwinStartup конфигурация:

string dir = AppDomain.CurrentDomain.RelativeSearchPath; // get executing path
string contentPath = Path.GetFullPath(Path.Combine(dir, @"../../../frontend/MyProjectApp")); // resolve nearby frontend project directory

app.UseFileServer(new FileServerOptions
{
    EnableDefaultFiles = true,
    FileSystem = new PhysicalFileSystem(contentPath),
    RequestPath = new PathString(string.Empty) // starts at the root of the host
});

// ensure the above occur before map handler to prevent native static content handler
app.UseStageMarker(PipelineStage.MapHandler);
Поймать

По сути, он просто размещает все вfrontend/MyProjectApp как будто это было прямо в корне MyProject.Host. Естественно, если вы запрашиваете файл, который не существует, IIS генерирует ошибку 404.

Теперь, потому что это приложение AngularJS, и оно поддерживаетhtml5modeУ меня будет несколько маршрутов, которые не являются физическими файлами на сервере, но обрабатываются как маршруты в приложении AngularJS. Если пользователь должен был перейти на AngularJS (что-либо кромеindex.html или файл, который физически существует, в этом примере), я бы получил 404, даже если этот маршрут может быть действительным в приложении AngularJS. Поэтому мне нужно мое промежуточное ПО OWIN для возвратаindex.html файл в том случае, если запрошенный файл не существует, и пусть мое приложение AngularJS выяснит, действительно ли это 404.

Если вы знакомы с SPA и AngularJS, это нормальный и прямой подход. Если бы я использовал маршрутизацию MVC или ASP.NET, я мог бы просто установить маршрут по умолчанию для контроллера MVC, который возвращает мойindex.html, Или что-то вдоль этих линий. Тем не менее, я уже заявил, что не использую MVC, и я стараюсь сделать это как можно проще и проще.

Этот пользователь У меня была похожая дилемма, и я решил ее с помощью переписывания IIS. В моем случае это не работает, потому что: а) мой контент не существует физически, где модуль перезаписи URL может его найти, поэтомувсегда возвращаетсяindex.html и б) я хочу что-то, что не зависит от IIS, но обрабатывается в промежуточном программном обеспечении OWIN, поэтому его можно использовать гибко.

TL; DNR меня, за то, что я громко плачу.

Просто, как я могу перехватить 404 Not Found и вернуть содержимое (примечание:не перенаправить) мойFileServer-servedindex.html используя промежуточное ПО OWIN?

Ответы на вопрос(4)

Ваш ответ на вопрос