5

Sto costruendo una soluzione client/server, utilizzando un'app singola pagina AngularJS come componente client e un'API RESTful SelfState host come componente server. Un singolo progetto di applicazione della console di Visual Studio contiene file HTML e JavaScript per il componente AngularJS, insieme alle classi C# per l'avvio del ServiceStack AppHost (ho delegato le responsabilità dell'interfaccia e del servizio per separare i progetti di Visual Studio).Come posso far funzionare AngularJS con l'attributo FallbackRoute di ServiceStack per supportare gli URL pushstate HTML5?

Ho impostato tutti i file HTML e JavaScript per avere una 'Build Action' di 'None' e una 'Copy to Output Directory' di 'Copy if newer'.

Tutto sta funzionando molto bene fino a quando sono pronto a sopportare di avere un "#" nei miei URL del sito. Vorrei eliminarlo usando gli URL dello spazio di stampa HTML5.

Questo significa che devo convincere ServiceStack a pubblicare la pagina di shell HTML della pagina singola predefinita ogni volta che viene richiesta una route inesistente. È ora disponibile l'attributo FallbackRouteavailable in ServiceStack che sembra essere stato aggiunto esattamente per questo scopo.

Tuttavia, non sono sicuro di come utilizzarlo. Ho trovato persone che facevano domande simili here, here e here. Ma le risposte fornite erano tutte precedenti all'arrivo del nuovo attributo FallbackRoute.

In sostanza, sto cercando un esempio semplice ma completo di come utilizzare l'attributo FallbackRoute per garantire che tutte le richieste di route inesistenti vengano reindirizzate a una singola pagina HTML statica.

risposta

3

si scopre che è tutto molto semplice con la funzionalità FallbackRoute, una volta che si lavora come usalo correttamente:

[FallbackRoute("/{Path*}")] 
    public class Fallback 
    { 
     public string Path { get; set; } 
    } 

    public class FallBackService : Service 
    { 
     public object Any(Fallback request) 
     { 
      return new HttpResult(new FileInfo("index.html")) {ContentType = "text/html"}; 
     } 
    } 

Una volta che questo è a posto, trovo che "index.html" viene effettivamente attivato ogni volta che provo a trovare un percorso inesistente.

Tutti i file statici, come le risorse JavaScript e CSS, vengono serviti come di consueto (purché abbiano l'impostazione 'Copia in Output Directory' di 'Copia se più recente', ovviamente).

Questo funziona come un fascino con la funzionalità Push-state HTML5 in AngularJS.

3

Il RazorRockstars.Web ha un'implementazione. Io modificarlo in modo da utilizzare un percorso con caratteri jolly e una visualizzazione predefinita:

[FallbackRoute("/{Path*}")] 
public class Fallback 
{ 
    public string Path { get; set; } 
    public string PathInfo { get; set; } 
} 

public class RockstarsService : Service 
{ 
    [DefaultView("Index")] 
    public object Any(Fallback request) 
    { 
     request.PathInfo = base.Request.PathInfo; 
     return request; 
    } 
    // ... 
} 

Dal momento che questo è un servizio che richiede una pagina View (details here), piuttosto che una pagina di contenuto.

Nell'esempio RockStars, non riesco a determinare quale vista sarebbe resa per FallBackResponse, ma impostare la vista in modo esplicito dovrebbe essere tutto ciò che serve.

L'attributo [DefaultView("Index")] aggiunto al metodo Any associa la risposta a un file Views/Index.cshtml. Il file Index.cshtml può essere vuoto, ma per una dichiarazione modello, e la marcatura completa per la tua pagina singola applicazione può essere nel vostro file di modello (ad esempio _Layout.cshtml)

Senza Razor

Leggi l'html in una stringa e restituirlo, durante l'impostazione del tipo di contenuto "text/html" con un attributo, vedere wiki docs on service return types

public class RockstarsService : Service 
{ 
    static string readContents; 

    [AddHeader(ContentType = "text/html")] 
    public string Any(Fallback request) 
    { 

     // check timestamp for changes for production use 
     if (readContents == '') { 
      using (StreamReader streamReader = new StreamReader(pathFromConfigFile, Encoding.UTF8)) 
      { 
       readContents = streamReader.ReadToEnd(); 
      } 
     } 
     return readContents; 
    } 
    // ... 
} 
+0

Questo è tutto molto bello. Tuttavia, preferirei non dover aggiungere il plug-in Razor se non è necessario. Sto usando una singola pagina HTML statica e sembrerebbe eccessivo usare un motore di template Razor solo per aggiungere una Fallback Route. – Holf

+0

aggiunto 'senza rasoio' opzione –

+0

Sembra molto bello ... ci proverò più tardi. Grazie! – Holf

Problemi correlati