URL Rewrite options: How to exclude files and directories?

Viewed 375

I'm using the URL rewrite middleware in ASP.NET Core, and I'm trying to make the rewrite work only if the request does not point to an existing file or directory.

Here's the code I'm using:

var options = new RewriteOptions()
    .AddRewrite(@"^(.*)$", "index.php/$1", skipRemainingRules: true);

app.UseRewriter(options);

In: Startup::Configure()

In IIS, using web.config, I can define something like this:

<rule name="RewriteRule" enabled="true" stopProcessing="false">
    <match url="^(.*)$" ignoreCase="true" />
    <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
    </conditions>
    <action type="Rewrite" url="index.php/{R:1}" appendQueryString="true" />
</rule>

Please notice the negate="true" attribute on matchType="IsFile" and matchType="IsDirectory", for input="{REQUEST_FILENAME}", which is the request path.

I do not want to load an IIS-style rewrite ruleset with AddIISUrlRewrite(), nor I'm confident that it'll work.

Is it possible to exclude existing static files from the rewrite request in ASP.NET Core? If so, how?

1 Answers

I wound up doing something like this - my static files are hosted under a sub-folder "Web":

var fileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Web"));

app.UseRewriter(new RewriteOptions() { StaticFileProvider = fileProvider }
    .Add(context =>
        {
            if (context.HttpContext.Request.Path.StartsWithSegments("/Web", out var subPath))
            {
                if (subPath != "/" && context.StaticFileProvider.GetDirectoryContents(subPath).Exists)
                {
                    context.Result = RuleResult.SkipRemainingRules;
                }
                else if (context.StaticFileProvider.GetFileInfo(subPath).Exists)
                {
                    context.Result = RuleResult.SkipRemainingRules;
                }
            }
        })
    .AddRewrite("^Web/(.*)$", "Web/index.html", true));

app.UseStaticFiles(new StaticFileOptions
                       {
                           FileProvider = fileProvider,
                           RequestPath = "/Web",
                       });
Related