7

Con RC1 di ASP.NET 1.0 Nucleo di MVC 6 è possibile mappare i percorsi all'interno vostra funzione Startup.Configure quando si richiama app.UseMvc. Ho tracciato un percorso "spa-fallback", che farà in modo che il HomeController e Index vista sono le impostazioni di default in questo modo:MVC 6 Routing, SPA fallback + 404 errore pagina

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

desidero il fallback in modo che le rotte mio Angular2 di app non si tradurrà in un HTTP Codice di stato di 404, non trovato. Ma devo anche gestire correttamente quando un utente tenta inavvertitamente di navigare verso una visualizzazione di pagina che non esiste. Potresti notare che ho anche chiamato app.UseStatusCodePagesWithRedirects("/Home/Error/{0}");.

La chiamata per reindirizzare alla mia pagina di errore con il codice di stato e l'itinerario "spa-fallback" sembrano escludono a vicenda - che significa che sembra che io possa avere solo uno o l'altro (ma purtroppo non entrambi). Qualcuno sa come potrei riuscire ad avere il meglio di entrambi i mondi?

+0

Attualmente il nuovo pacchetto è disponibile in "Microsoft.AspNetCore.SpaServices": "1.0.0-beta-000005". –

+0

@SamanAhmadi, ho visto che ...grazie –

+0

@DavidPine prenderemo in considerazione la modifica della risposta accettata? Cercando di costruire il mio credito per la strada ;-) –

risposta

12

Mi ci è voluto un po 'di tempo per capire come farlo senza servire il mio indice usando MVC e ancora ricevere 404 per i file mancanti. Ecco la mia pipeline 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(); 
     });    
    } 
+0

Grazie per aver esaminato questo aspetto, avrei dovuto aggiornare la mia domanda o cancellarla prima, poiché l'avevo già capito dopo il fatto. –

+0

Questa soluzione è piacevole poiché non richiede MVC. Attualmente sto usando ASP.NET come un file server statico (senza MVC), ma voglio essere in grado di reindirizzare percorsi non attivi a 'index.html'. –

+1

Nizza risposta mi consiglia di utilizzare un po 'meglio il codice per l'Quando predicate: 'context => context.Response.StatusCode == 404 && Path.HasExtension (context.Request.Path.Value)' –

3

Mi sono venuti in mente due possibili soluzioni/soluzioni.

ASP.NET core 1.0, RC1

Con Angular2 In particolare, possiamo semplicemente scambiare il LocationStrategy. Per esempio nel mio wwwroot/app/boot.ts Ho il seguente:

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

nota che sto utilizzando la funzione provide per ignorare lo standard LocationStrategy con l'HashLocationStrategy. Ciò aggiunge il # nella URL e impedisce MVC dal gettare errato 404 di, ma anche correttamente maniglie rispondere con 404 del quando l'utente manualmente che non esiste tipi in un URL.

ASP.NET core 1.0, RC2

sufficiente utilizzare Microsoft.AspNet.NodeServices. All'interno di questa libreria ci sono sia AngularServices che ReactServices che consentono specificamente la mappatura delle rotte SPA, tramite la funzione MapSpaFallbackRoute. Premetto che dobbiamo aspettare RC2 con la consapevolezza che le attuali implementazioni non stanno funzionando pienamente come desiderato.

+0

Grazie per avermelo fatto sapere, sto andando a dare un'occhiata. Dal lato angolare, non volevo usare la strategia di localizzazione hash poiché non è richiesta con i browser html5. –

0

Prova questa:

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() cattura tutte le richieste che non corrisponde a nessuno dei percorsi definiti in precedenza. In questo modo è possibile ottenere il fallback personalizzato per spa e utilizzare app.UseStatusCodePagesWithRedirects() allo stesso tempo.