7

Z RC1 z ASP.NET MVC Rdzeń 1,0 za 6 można mapować trasy z poziomu funkcji Startup.Configure podczas wywoływania app.UseMvc. Mam mapowane do „spa-awaryjnej” trasą, która zapewni, że HomeController i Index widok są domyślnie tak:MVC 6 Routing, SPA awaryjna + 404 Error Page

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?}"); 
    }); 
} 

pragnę fallback tak że szlaki mojego Angular2 aplikacji nie spowoduje HTTP Kod stanu 404, nie znaleziono. Ale muszę również poprawnie obsługiwać, gdy użytkownik nieumyślnie próbuje przejść do widoku strony, który nie istnieje. Możesz zauważyć, że nazwałem również app.UseStatusCodePagesWithRedirects("/Home/Error/{0}");.

Wywołanie przekierowania na moją stronę błędu z kodem statusu i trasą "spa-backback" wydaje się wzajemnie wykluczające - co oznacza, że ​​wydaje mi się, że mogę mieć tylko jedną lub drugą (ale niestety nie obie). Czy ktoś wie, w jaki sposób udaje mi się osiągnąć to, co najlepsze z obu światów?

+0

Obecnie nowy pakiet można znaleźć w "Microsoft.AspNetCore.SpaServices": "1.0.0-beta-000005". –

+0

@SamanAhmadi, widziałem to ...dziękuję –

+0

@DavidPine czy rozważasz zmianę akceptowanej odpowiedzi? Próbuję zbudować moją uliczną wiarygodność ;-) –

Odpowiedz

12

Zajęło mi trochę czasu, aby dowiedzieć się, jak to zrobić bez podawania mojego indeksu za pomocą MVC i nadal otrzymywać 404s za brakujące pliki. Oto mój http rurociąg:

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(); 
     });    
    } 
+0

Dziękuję za rozpatrzenie tego, powinienem był zaktualizować moje pytanie lub usunąć je wcześniej - odkąd już to odkryłem po fakcie. –

+0

To rozwiązanie jest dobre, ponieważ nie wymaga posiadania MVC. Obecnie używam ASP.NET jako statyczny serwer plików (bez MVC), ale chcę mieć możliwość przekierowania ścieżek innych niż "asset.html" do 'index.html'. –

+1

Nicea odpowiedź Polecam używanie nieznacznie lepszy kod dla When orzecznik: 'context => context.Response.StatusCode == 404 && Path.HasExtension (context.Request.Path.Value)' –

3

Wymyśliłem dwa możliwe rozwiązania/rozwiązania.

Rdzeń ASP.NET 1.0 RC1

Z Angular2 konkretnie, możemy po prostu zamienić się z LocationStrategy. Na przykład w moim wwwroot/app/boot.ts mam następujące:

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 }) 
    ]); 

Zauważ, że jestem z wykorzystaniem funkcji provide aby zastąpić standardową LocationStrategy z HashLocationStrategy. To dodaje # w adresie URL i zapobiega MVC z nieprawidłowo rzucanie 404 na, ale również prawidłowo obsługuje odpowiadając 404 na gdy użytkownik ręcznie typów w URL że nie istnieje.

Rdzeń ASP.NET 1.0 RC2

Wystarczy użyć Microsoft.AspNet.NodeServices. W tej bibliotece znajdują się zarówno AngularServices, jak i ReactServices, które umożliwiają mapowanie tras SPA w szczególności za pośrednictwem funkcji MapSpaFallbackRoute. Oświadczam, że musimy poczekać na RC2 przy założeniu, że obecne implementacje nie działają w pełni zgodnie z oczekiwaniami.

+0

Dzięki za poinformowanie mnie o tym, zamierzam to sprawdzić. Po stronie kątowej nie chciałem korzystać ze strategii hash, ponieważ nie jest ona wymagana w przeglądarkach html5. –

0

Spróbuj:

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() złapie wszystkie żądania, które nie pasują do żadnej z tras zdefiniowanych wcześniej. W ten sposób można uzyskać niestandardową awaryjną funkcję spa i jednocześnie używać app.UrządzajKodamiProgramówWithRedirects().