MVC 6路由,SPA后备+ 404错误页面

使用ASP.NET Core 1.0的MVC 6的 RC1 ,您可以在调用app.UseMvc时从Startup.Configure函数中映射路由。 我已经映射了一个“spa-fallback”路由,它将确保HomeControllerIndex视图是默认值,如下所示:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { // ... omitted for brevity app.UseExceptionHandler("/Home/Error"); app.UseStatusCodePagesWithRedirects("/Home/Error/{0}"); app.UseMvc(routes => { routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); routes.MapRoute("spa-fallback", "{*anything}", new { controller = "Home", action = "Index" }); routes.MapWebApiRoute("defaultApi", "api/{controller}/{id?}"); }); } 

我希望回退,以便我的Angular2应用程序的路由不会导致HTTP状态代码为404,Not Found 。 但是,当用户无意中尝试导航到不存在的页面视图时,我还需要正确处理。 您可能会注意到我还调用了app.UseStatusCodePagesWithRedirects("/Home/Error/{0}");

使用状态代码和“spa-fallback”路由重定向到我的错误页面的调用似乎是互斥的 – 这意味着我似乎只能拥有一个或另一个(但遗憾的是不是两者) 。 有谁知道如何才能让两全其美?

我花了一些时间来弄清楚如何在不使用MVC提供索引的情况下执行此操作,并仍然收到丢失文件的404。 这是我的http管道:

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseDefaultFiles(); app.UseStaticFiles(); app.UseMvc( routes => { routes.MapRoute( name: "api", template: "api/{controller}/{action}/{id?}"); // ## commented out since I don't want to use MVC to serve my index. // routes.MapRoute( // name:"spa-fallback", // template: "{*anything}", // defaults: new { controller = "Home", action = "Index" }); }); // ## this serves my index.html from the wwwroot folder when // ## a route not containing a file extension is not handled by MVC. // ## If the route contains a ".", a 404 will be returned instead. app.MapWhen(context => context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value), branch => { branch.Use((context, next) => { context.Request.Path = new PathString("/index.html"); Console.WriteLine("Path changed to:" + context.Request.Path.Value); return next();}); branch.UseStaticFiles(); }); } 

我提出了两种可能的解决方法/解决方案。

ASP.NET Core 1.0,RC1

有了Angular2 ,我们可以简单地换掉LocationStrategy 。 例如在我的wwwroot/app/boot.ts我有以下内容:

 import {provide} from "angular2/core"; import {bootstrap} from "angular2/platform/browser"; import {LocationStrategy, HashLocationStrategy, ROUTER_PROVIDERS} from "angular2/router"; import {HTTP_PROVIDERS} from "angular2/http"; import {AppComponent} from "./app.component" bootstrap(AppComponent, [ ROUTER_PROVIDERS, HTTP_PROVIDERS, provide(LocationStrategy, { useClass: HashLocationStrategy }) ]); 

请注意,我正在使用provide函数来使用HashLocationStrategy覆盖标准LocationStrategy 。 这会在URL中添加#并阻止MVC错误地抛出404 ,但在用户手动键入不存在的URL时也能正确处理404的响应。

ASP.NET Core 1.0,RC2

只需使用Microsoft.AspNet.NodeServices 。 在这个库中有AngularServicesReactServices ,它们允许通过MapSpaFallbackRoute函数专门映射SPA路由。 我声明我们需要等待RC2 ,同时理解当前的实现并没有按照需要完全运行。

试试这个:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseExceptionHandler("/Home/Error"); app.UseStatusCodePagesWithRedirects("/Home/Error/{0}"); app.UseMvc(routes => { routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); routes.MapWebApiRoute("defaultApi", "api/{controller}/{id?}"); }); app.Run(async context => { context.Response.Redirect("/Home/Index"); await Task.CompletedTask; }); } 

app.Run()将捕获与之前定义的任何路由不匹配的所有请求。 这样您就可以获得自定义spa回退并同时使用app.UseStatusCodePagesWithRedirects()。

Interesting Posts