2014-12-01 8 views
11

Ich mache ein SPA, das auf ASP.Net WebAPI sitzt. Ich warte darauf, HTML5-Verlauf anstelle von #/ für Verlaufsrouting zu verwenden, aber das stellt ein Problem für Deep-Linking, muss ich sicherstellen, / und /foo/bar alle die gleiche HTML-Datei zurückgeben (und mein JS wird den rechten Teil des SPA wiedergeben) .OWIN statische Datei für mehrere Routen senden

Wie bekomme ich OWIN/Katana, um dieselbe HTML-Datei für mehrere verschiedene URLs zurückzugeben?

+0

Sie möchten also, dass jede URL, die den Server trifft, index.html mit statischer Middleware bedient? – khellang

+0

Ja, eine beliebige Route (oder eine Route, die mit '/ app/*' übereinstimmt) gibt die Datei 'index.html' zurück. –

Antwort

21

Um die Dinge einfach zu machen, während noch alles Gutes Caching zu halten usw. von der Staticmiddleware, würde ich eine Inline-Middleware die Anforderung Pfad, wie diese

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

Dies wird dazu dienen, den Service umschreiben nur Seite auf alles außer /app/*, die immer Index.html dienen wird.

0

Ich stieß auf ein ähnliches Problem mit Angular js und verwendete einen etwas anderen Ansatz, um das Problem zu lösen.

Wir verwendeten Owin, um eine Route zum Einstiegspunkt des SPA (index.html) zu kartieren. Dadurch können Sie auf das SPA zugreifen und zu den verschiedenen Seiten navigieren. Allerdings, wenn Sie die Seite jemals aktualisiert haben, würden Sie einen 404 erhalten. Im Wesentlichen traten AngularJS Routing und Owin/Katana Routing auf die Zehen.

Ich habe das Problem gelöst, indem ich einen benutzerdefinierten DelegatingHandler erstellt habe. Dieser delegierende Handler wird verwendet, wenn Owin/Katana keine Route finden kann, die der Anfrage entspricht (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; 
    } 
} 

Das Snippet oben kehrt index.html, der Einstiegspunkt des SPA, wenn wir nicht in der Lage sind, eine Seite zu finden, die Anfrage entsprechen.

Um diese delegierenden Handler zu verwenden, können Sie die folgende Zeile in HttpConfiguration müssen hinzufügen(), wenn der Host Owin Start:

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

Kurz gesagt, ich habe eine Standardroute, die mit dem SPA abbildet, und jede nicht erkannte Route wird über den DelegierenHandler geleitet und bedient denselben SPA. Wir ändern den Request.Path nicht, sodass der SPA die Anforderung an die richtige Seite weiterleiten kann.

+0

Dies wird etwas funktionieren, aber in vielen Fällen wird es ratsam sein, eine solche Implementierung in der Produktion zu verwenden. File.ReadAllText erkennt die Codierung automatisch (was Probleme verursachen könnte) und ist nicht so effizient wie andere Ansätze. –

+0

Danke für Ihre Eingabe. Also schlagen Sie vor, dass ich eine Lösung verwende, die der akzeptierten Antwort ähnlich ist, oder gibt es eine Alternative zu File.ReadAllText, die bevorzugt wird? – Justin

Verwandte Themen