ASP.NET Core map route to static file handler

2019-06-18 23:18发布

I'm working on a ASP.NET Core website (previously named ASP.NET 5 / vNext) with Angular. In order for Angular to work I need to have a catch-all route:

app.UseStaticFiles(); 
app.UseMvc(routes =>
        {
            // Angular fallback route
            routes.MapRoute("angular", "{*url}", new { controller = "Home", action = "Index" });                
        });

I also have a few files/folders in wwwroot, like:

wwwroot/app
wwwroot/assets
wwwroot/lib

When any requests are made to these paths, for example http://example.com/assets/css/test.css, and the file (test.css) does NOT exist, it should not continue to the fallback route. It should return a 404.

Right now, if the file does not exist it returns the Angular HTML. So, how can I tell it that any path that starts with '/assets' should only be routed / served by UseStaticFiles?

Thanks.

2条回答
聊天终结者
2楼-- · 2019-06-19 00:01

It is strange that this common case (since many use SPA) is not covered almost anywhere and everyone has to invent something. I have found that the best way to do that is to add constraint (e.g. do not use the route if there is /api or "." in the path). Unfortunately this is not supported out of the box, but you can write this constraint yourself or copy the one I wrote from here.

There are a bit more details in this post. But generally the code looks like this:

 app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "api",
            template: "api/{controller}/{action}");

        routes.MapRoute(
            name: "angular",
            template: "{*url}",
            defaults: new {controller = "Home", action = "Index"},
            constraints: new {url = new DoesNotContainConstraint(".", "api/") });                
    });

P.S. Perhaps this constraint exist out of the box now, but I have not found one. Alternatively a RegEx can be used, but simple one should be way faster.

查看更多
做自己的国王
3楼-- · 2019-06-19 00:10

This seems to work:

app.MapWhen(context =>
        {
            var path = context.Request.Path.Value;
            return path.StartsWith("/assets", StringComparison.OrdinalIgnoreCase) ||
                   path.StartsWith("/lib", StringComparison.OrdinalIgnoreCase) ||
                   path.StartsWith("/app", StringComparison.OrdinalIgnoreCase);
        }, config => config.UseStaticFiles());

However, I'm not sure if there are any performance (or other type of) implications. I'll update if I come across any.

查看更多
登录 后发表回答