MVC 6 路由,SPA 回退 + 404 错误页面
MVC 6 Routing, SPA fallback + 404 Error Page
使用 ASP.NET Core 1.0 的 MVC 6 的 RC1,您可以在调用 Startup.Configure
函数时映射路由 app.UseMvc
。我已经映射了一个 "spa-fallback" 路由,它将确保 HomeController
和 Index
视图是默认值,如下所示:
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 为我的索引提供服务的情况下执行此操作,并且仍然收到丢失文件的 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();
});
}
我想出了两个可能 workarounds/solutions。
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's,但也会正确处理响应 404's当用户手动输入不存在的 URL 时。
ASP.NET 核心 1.0, RC2
只需使用Microsoft.AspNet.NodeServices
. Within this library there are both AngularServices
and ReactServices
which allow for the mapping of SPA routes specifically, via the MapSpaFallbackRoute
函数。我声明我们需要等待 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() 将捕获所有与之前定义的任何路由都不匹配的请求。通过这种方式,您可以获得自定义水疗后备并同时使用 app.UseStatusCodePagesWithRedirects()。
使用 ASP.NET Core 1.0 的 MVC 6 的 RC1,您可以在调用 Startup.Configure
函数时映射路由 app.UseMvc
。我已经映射了一个 "spa-fallback" 路由,它将确保 HomeController
和 Index
视图是默认值,如下所示:
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 为我的索引提供服务的情况下执行此操作,并且仍然收到丢失文件的 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();
});
}
我想出了两个可能 workarounds/solutions。
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's,但也会正确处理响应 404's当用户手动输入不存在的 URL 时。
ASP.NET 核心 1.0, RC2
只需使用Microsoft.AspNet.NodeServices
. Within this library there are both AngularServices
and ReactServices
which allow for the mapping of SPA routes specifically, via the MapSpaFallbackRoute
函数。我声明我们需要等待 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() 将捕获所有与之前定义的任何路由都不匹配的请求。通过这种方式,您可以获得自定义水疗后备并同时使用 app.UseStatusCodePagesWithRedirects()。