2014-12-01 19 views
11

Sto creando una SPA che si trova su ASP.Net WebAPI. Sto aspettando di utilizzare la cronologia HTML5 anziché lo #/ per il routing della cronologia ma ciò pone un problema per il deep linking, ho bisogno di assicurarmi che / e /foo/bar restituiscano tutti lo stesso file HTML (e il mio JS renderà la parte destra della SPA) .OWIN invia file statico per più route

Come si ottiene OWIN/Katana per restituire lo stesso file HTML per più URL diversi?

+0

Quindi vuoi che qualsiasi URL colpisca il server per servire index.html usando il middleware di file statici? – khellang

+0

Sì, qualsiasi percorso (o qualsiasi percorso corrispondente a '/ app/*') restituirà il file 'index.html'. –

risposta

21

Per rendere le cose semplici, pur mantenendo tutta la bontà di caching ecc dal middleware StaticFiles, avevo appena riscrivere il percorso richiesta utilizzando un middleware in linea, come questo

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     app.Map("/app", spa => 
     { 
      spa.Use((context, next) => 
      { 
       context.Request.Path = new PathString("/index.html"); 

       return next(); 
      }); 

      spa.UseStaticFiles(); 
     }); 

     app.UseWelcomePage(); 
    } 
} 

Questo servirà l'accoglienza pagina su tutto tranne /app/*, che servirà sempre index.html invece.

0

Ho riscontrato un problema simile utilizzando Angular js e ho utilizzato un approccio leggermente diverso per risolvere il problema.

Abbiamo utilizzato Owin per mappare un percorso verso il punto di ingresso della SPA (index.html). Questo ti consente di accedere alla SPA e navigare nelle diverse pagine. Tuttavia, se avessi mai aggiornato la pagina, avresti ottenuto un 404. Essenzialmente, il routing di AngularJS e il routing di Owin/Katana si stavano calpestando l'un l'altro.

Ho risolto il problema creando un DelegatingHandler personalizzato. Questo gestore delegante viene utilizzato ogni volta che Owin/Katana non è in grado di trovare una route corrispondente alla richiesta (404).

public class CustomDelegatingHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     Task<HttpResponseMessage> response = base.SendAsync(request, cancellationToken); 
     if (response.Result.StatusCode == HttpStatusCode.NotFound) 
     { 
      response.Result.Content = new StringContent(File.ReadAllText(@"index.html")); 
      response.Result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html"); 
      response.Result.StatusCode = HttpStatusCode.OK; 
     } 
     return response; 
    } 
} 

Il frammento precedente restituisce index.html, il punto di ingresso della SPA, quando siamo in grado di trovare una pagina corrispondente alla richiesta.

Per poter utilizzare questo gestore delegante, è necessario aggiungere la seguente riga al HttpConfiguration() quando si avvia l'host Owin:

 var httpConfig = new HttpConfiguration(); 
     httpConfig.MessageHandlers.Add(new CustomDelegatingHandler()); 

Insomma, ho un percorso predefinito che mappa alla SPA, e qualsiasi percorso non riconosciuto passerà attraverso il DelegatingHandler e servirà la stessa SPA. Non modifichiamo il Request.Path, consentendo alla SPA di indirizzare la richiesta alla pagina corretta.

+0

Ciò funzionerà in qualche modo ma in molti casi, sarà consigliabile utilizzare tale implementazione in produzione. File.ReadAllText rileverà automaticamente la codifica (che potrebbe causare problemi) e non sarà efficiente come altri approcci. –

+0

Grazie per l'input. Quindi mi suggerisce di utilizzare una soluzione simile alla risposta accettata o esiste un'alternativa a File.ReadAllText che è preferibile? – Justin

Problemi correlati