MVC6路由到单页面应用程序而不会丢失404

Emd*_*dot 7 asp.net-core-mvc angular2-routing

我正在用angular2和MVC5编写单页应用程序.不过,我对两者都很陌生,而且我在路由方面遇到了麻烦.

我想将网址匹配为:

  • / - >转到我的索引页面,其中bootstraps angular
  • /api/{controller}/{id?} - > REST API
  • /{*anythingelse} - >如果存在文件,则将其作为静态内容返回; 否则,如果角度可以路由它,有角度路线; 否则返回404.

第二点很容易,如果我愿意放弃404返回,我可以让客户端路由工作,但我似乎无法调和它.

看起来应该这样:

app.UseStaticFiles();
app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "api",
        template: "api/{controller}/{id?}");
    routes.MapRoute(
        name: "spa",
        template: "{*anythingelse}",
        defaults: new { controller = "Home", action = "Index" });
});
Run Code Online (Sandbox Code Playgroud)

和:

@RouteConfig([
    { path: "/", name: 'Splash', component: SplashView },
    { path: '/accounts/login', name: 'Login', component: LoginView },
    { path: '/accounts/register', name: 'Registration', component: RegistrationView },
    { path: '/home/...', name: 'Home', component: HomeView },
])
Run Code Online (Sandbox Code Playgroud)

但是,这只是为每个不是静态文件的请求提供Index.cshtml.

我觉得这已经是一个已经解决的问题,但我无法在网上找到任何关于它的信息.如何正确地做到这一点?

我使用的是"HTML5"风格的路径,而不是散列风格.

Mor*_*n G 0

所以有两种方法可以做到这一点。如果您正在使用 HashLocationStrategy,我强烈鼓励您在服务器端实现上执行此操作,因为我发现它更容易处理。

否则,您可以创建自己的 RouterOutlet 组件来处理异常。我不是 100% 清楚如何让它与 RouterConfig 一起工作,因为我还没有深入研究路由方面,但我打赌你可以看到是否存在路由,然后去那里,否则会出现 404 错误。这是我的代码,用于查看用户是否使用 Json Web 令牌登录。

import {Directive, Attribute, ElementRef, DynamicComponentLoader} from 'angular2/core';
import {Router, RouterOutlet, ComponentInstruction} from 'angular2/router';

@Directive({
  selector: 'router-outlet'
})
export class LoggedInRouterOutlet extends RouterOutlet {
  publicRoutes: any;
  private parentRouter: Router;

  constructor(_elementRef: ElementRef, _loader: DynamicComponentLoader,
              _parentRouter: Router, @Attribute('name') nameAttr: string) {
    super(_elementRef, _loader, _parentRouter, nameAttr);

    this.parentRouter = _parentRouter;

  }

  activate(instruction: ComponentInstruction) {

    if (!localStorage.getItem('jwt') || !tokenNotExpired('jwt')) {//Public Routes does not work with Hash Location Strategy, need to come up with something else.
      // todo: redirect to Login, may be there is a better way?
      if(localStorage.getItem('jwt')){
        localStorage.removeItem('jwt');
      }
      this.parentRouter.navigate(['Login']);
    }
    return super.activate(instruction);
  }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我负责检查令牌,如果他们没有令牌,他们只能转到我的登录页面。然后在您的 app.component 或引导组件中,只需使用它作为您的路由器出口,而不是原始的。

抱歉,我无法提供更多帮助,但我希望这能为您指明正确的方向!