2016-02-20 21 views
7

私はangular2とMVC5を使ってシングルページアプリケーションを作成しています。私は両方の新しいですが、私はルーティングに問題があります。私のようにURLを一致したいと思いますMVC6は単一ページアプリケーションへのルーティングを失うことなく404

:ファイルが存在する場合> -

  • / - > RESTのAPI
  • /{*anythingelse} - >私のインデックスページ、ブートストラップの角度
  • /api/{controller}/{id?}に行きます静的コンテンツとして返します。さもなければ、角度がそれを送ることができるならば、角度のあるルートを持ってください;そうでなければ404を返します。

2つ目のポイントは簡単です.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" }); 
}); 

と::

はこれが働くべきように思える

@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 }, 
]) 

をしかし、それは単なる静的なファイルではありませんすべての要求に対してIndex.cshtmlを提供しています。

私はこれがすでに解決されている必要があるように感じますが、私はそれについてオンラインで何かを見つけることができませんでした。どのようにこれを正しく行うのですか?

ハッシュスタイルではなく「HTML5」スタイルのパスを使用しています。

+0

で始まるすべての要求へのすべてのルートがあなたのREST APIが使用しているあなたのキャッチを防ぐことができますWebApi? WebApiはMVCとは別のフレームワークであり、独自のルート構成を持っています。 MVC(WebApiではなく)を使用している場合は、正しく設定されていません。デフォルトアクション 'defaults:new {action =" Index "}'またはURL 'api/{controller}/{アクション}/{id?} '。 – NightOwl888

+0

また、経路の順序についてのあなたの前提は不可能です。Angularはブラウザで実行されるため、最初にルーティングされます。それ以外の場合は、サーバー側で構成した順番に、構成したルートが試行されます。リクエストがサーバーにヒットしたら、もう一度Angularに制御を戻すことはできません。 – NightOwl888

+0

ああ、私の謝罪。私はMVC5を落としましたが、ASP.NET 5ではMVC6を意味していました.ASP.NET 5では、WebAPIとMVCのルータがマージされました。 – Emdot

答えて

0

だから、それをやり遂げるには2つの方法があります。 HashLocationStrategyを使用している場合、私はこれを扱う方がはるかに簡単であることがわかっているので、サーバー側の実装でこれを行うことを強くお勧めします。

そうしないと、例外を処理する独自のRouterOutletコンポーネントを作成できます。私はあなたがそれをあなたのRouterConfigと一緒に働かせる方法を100%明確にしているわけではありません。しかし、私はルーティングアスペクトの深いところを掘り下げませんでしたが、経路が存在するかどうかを見ることができます。ここでは、ユーザーが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); 
    } 
} 

トークンがない場合は、自分のログインページに行くことができます。その後、app.componentまたはブートストラップされたコンポーネントで、これを元のルータの代わりにルータのアウトレットとして使用してください。

申し訳ありません申し訳ありませんが、私はこれ以上役に立つとは限りませんが、これが正しい方向に向いていることを願っています。

+0

おそらく私は単純に高密度ですが、上書きされたRouterOutlet(クライアント側)から404(サーバー側)にどのように移行しているのかはわかりません。 – Emdot

+0

それでは、私があなたに示したいことは、同じ種類の機能を持つ 'if RouterConfig route 404'を扱うことができるということです。受信したすべてのURLがあなたの新しいルータのアウトレットを通過し、チェックを行うからです。 –

+0

恐らく、見つからないページが「404」と表示されていますか?私は実際の404 HTTP応答コードをWebサーバーから探しています。 – Emdot

0

私はあなたが正規表現ルート制約を探していると思う:

routes.MapRoute("app", "{*anything}", 
    new { controller = "Home", action = "Index" }, 
    new {anything = new RegexRouteConstraint("^(?!api\\/).+") }); 

これは、マッピングから「API /」

関連する問題