ASP.NET核心映射路由到静态文件处理程序

时间:2016-02-23 20:27:44

标签: asp.net-mvc asp.net-mvc-5 asp.net-core asp.net-core-mvc

我正在使用Angular在ASP.NET Core网站(以前称为ASP.NET 5 / vNext)上工作。为了使Angular能够工作,我需要有一个全能的路线:

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

我在wwwroot中也有一些文件/文件夹,例如:

wwwroot/app
wwwroot/assets
wwwroot/lib

如果对这些路径发出任何请求,例如http://example.com/assets/css/test.css,并且文件(test.css)不存在,则不应继续执行回退路由。它应该返回404。

现在,如果该文件不存在,则返回Angular HTML。那么,我怎么能告诉它任何以'/ assets'开头的路径只能由UseStaticFiles路由/提供?

感谢。

3 个答案:

答案 0 :(得分:6)

这似乎有效:

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());

但是,我不确定是否有任何表现(或其他类型)影响。如果我遇到任何问题,我会更新。

答案 1 :(得分:3)

奇怪的是,这种常见情况(因为很多使用SPA)几乎没有涵盖任何地方,每个人都必须发明一些东西。我发现最好的方法是添加约束(例如,如果路径中有/ api或“。”则不要使用路由)。不幸的是,这不支持开箱即用,但您可以自己编写此约束或复制我从here编写的约束。

post中有更多详细信息。但通常代码看起来像这样:

 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。也许这种约束现在开箱即用,但我还没找到。或者可以使用RegEx,但简单的应该更快。

答案 2 :(得分:0)

如果您使用的是属性模板路由,则可以应用以下简洁的解决方案:

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

因此此操作将忽略所有以跳过开头的路线。
如果您需要多个前缀或其他任何内容,则只需更新正则表达式即可。
需要第一个Get属性来处理站点的根(在这种情况下,route变量为 null )。