MVC 6 路由、SPA 回退 + 404 错误页面

本文关键字:错误 回退 路由 SPA MVC | 更新日期: 2023-09-27 18:34:02

使用 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,未找到。但是,当用户无意中尝试导航到不存在的页面视图时,我还需要正确处理。你可能会注意到我也打电话给app.UseStatusCodePagesWithRedirects("/Home/Error/{0}");.

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

MVC 6 路由、SPA 回退 + 404 错误页面

我花了一些时间来弄清楚如何在不使用 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 核心 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 酷睿 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() 将捕获与之前定义的任何路由不匹配的所有请求。通过这种方式,您可以获得自定义水疗后备并使用应用程序。UseStatusCodePagesWithRedirects() 同时。