ASP.NET Core map route to static file handler

戏子无情 提交于 2019-12-08 19:42:15

问题


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.


回答1:


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.




回答2:


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:


If you are using attribute template routing then you can apply this elegant solution:

[HttpGet("")]
[HttpGet("{*route:regex(^(?!skipped).*$)}")]
public async Task<IActionResult> Default(string route) { throw new NotImplementedException(); }

So all routes started with skipped will be ignored by this action.
If you want multiple prefixes or anything else then just update regex for your needs.
First Get attribute is needed to handle root of site (in this case route variable is null).



来源:https://stackoverflow.com/questions/35587488/asp-net-core-map-route-to-static-file-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!