Как использовать промежуточное ПО OWIN для перезаписи версии URL-адреса для запроса к статическому файлу?

например У меня есть файл, расположенный на сервере по адресу /Content/static/home.html. Я хочу иметь возможность сделать запрос к /Content/v/1.0.0.0/static/home.html (для управления версиями) и переписать URL-адрес, чтобы он обращался к файлу по правильному URL-адресу, используя промежуточное ПО OWIN.

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


person Ben Wilde    schedule 07.07.2014    source источник


Ответы (3)


Я нашел решение, используя пакет Microsoft.Owin.StaticFiles nuget:

Сначала убедитесь, что это есть в вашей веб-конфигурации, чтобы запросы статических файлов отправлялись в OWIN:

<system.webServer>
    ...
    <modules runAllManagedModulesForAllRequests="true"></modules>
    ...
</system.webServer>

Затем в методе Startup Configuration добавьте этот код:

// app is your IAppBuilder
app.Use(typeof(MiddlewareUrlRewriter));
app.UseStaticFiles();
app.UseStageMarker(PipelineStage.MapHandler);

А вот и MiddlewareUrlRewriter:

public class MiddlewareUrlRewriter : OwinMiddleware
{
    private static readonly PathString ContentVersioningUrlSegments = PathString.FromUriComponent("/content/v");

    public MiddlewareUrlRewriter(OwinMiddleware next)
        : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        PathString remainingPath;
        if (context.Request.Path.StartsWithSegments(ContentVersioningUrlSegments, out remainingPath) && remainingPath.HasValue && remainingPath.Value.Length > 1)
        {
            context.Request.Path = new PathString("/Content" + remainingPath.Value.Substring(remainingPath.Value.IndexOf('/', 1)));
        }

        await Next.Invoke(context);
    }
}

Например, это позволит запросу GET к /Content/v/1.0.0.0/static/home.html получить файл по адресу /Content/static/home.html.

ОБНОВЛЕНИЕ: добавлен app.UseStageMarker(PipelineStage.MapHandler); после других методов app.Use, так как это необходимо для работы. http://katanaproject.codeplex.com/wikipage?title=Static%20Files%20on%20IIS< /а>

person Ben Wilde    schedule 08.07.2014

Теоретически вы можете сделать это, используя UseStaticFiles с опциями вместо отдельного промежуточного программного обеспечения UrlRewriter:

string root = AppDomain.CurrentDomain.BaseDirectory;
var staticFilesOptions = new StaticFileOptions();
staticFilesOptions.RequestPath = new PathString("/foo");
staticFilesOptions.FileSystem = 
          new PhysicalFileSystem(Path.Combine(root, "web"));
app.UseStaticFiles(staticFilesOptions);

Но см. этот вопрос, так как в настоящее время он не работает.

person Ian Mercer    schedule 08.07.2014
comment
Можете ли вы показать, как это может учитывать любую версию в URL-адресе, согласно примеру в вопросе? - person Ben Wilde; 08.07.2014
comment
Он не может обрабатывать любую версию, вам нужно будет повторить это для каждой версии, которую вы хотите, но в вопросе была только одна версия. Если вам нужно, чтобы все версии были сопоставлены с одним и тем же набором ресурсов, тогда да, ваш переписчик URL может быть более подходящим. - person Ian Mercer; 08.07.2014
comment
Это не работает для меня. Я использую промежуточное ПО Owin StaticFiles версии 4.0. Как я могу диагностировать? - person Vunb; 28.02.2018