2011-01-13 10 views
9

Così ho un percorso come questo nella mia applicazione MVC 3 in esecuzione in IIS 7:MVC routing quando un file in realtà esiste nel percorso specificato

routes.MapRoute(
       "VirtualTourConfig", 
       "virtualtour/config.xml", 
       new { controller = "VirtualTour", action = "Config" } 
       ); 

Il trucco è che un file esiste effettivamente a/virtualtour/config.xml. Sembra che la richiesta stia appena restituendo il file xml in quella posizione invece di colpire il percorso, che elabora l'XML, apporta alcune modifiche e restituisce un XmlResult personalizzato.

Qualche suggerimento su come posso dire alla mia applicazione di raggiungere la rotta e non il file effettivo nel caso in cui il file esista su disco?

EDIT: Sembra che posso usare routes.RouteExistingFiles = true; nel metodo RegisterRoutes di Global.asax a dire l'applicazione di ignorare i file su disco. Questo, tuttavia, imposta il flag a livello globale e interrompe molte altre richieste all'interno dell'applicazione. Ad esempio, desidero ancora chiamare /assets/css/site.css per restituire il file CSS senza dover impostare in modo specifico i percorsi per ogni asset statico. Quindi ora la domanda diventa, c'è un modo per farlo su una base per rotta?

+3

Non credo ci sia un modo semplice per raggiungere questo obiettivo. Perché non sposti semplicemente il file statico nella cartella '~/App_Data'? –

risposta

6

Finora la migliore risposta a questo che ho trovato è applicare globalmente routes.RouteExistingFiles=true e quindi ignorare selettivamente i percorsi che voglio passare attraverso file esistenti come .js, .css, ecc. Così ho finito con qualcosa di simile this:

public static void RegisterRoutes(RouteCollection routes) 
     { 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
      routes.IgnoreRoute("*.js|css|swf"); 
      routes.RouteExistingFiles = true; 

      routes.MapRoute(
       "VirtualTourConfig", 
       "virtualtour/config.xml", 
       new { controller = "VirtualTour", action = "Config" } 
       ); 
} 

Se qualcuno ha una soluzione migliore, mi piacerebbe vederlo. Preferirei applicare selettivamente una bandiera "RouteExistingFIles" a percorsi individuali, ma non so se c'è un modo per farlo.

0

Nessuna soluzione qui, solo un'idea.

È possibile provare a implementare una soluzione basata sul proprio VirtualPathProvider che fornirà la propria mappatura dei percorsi Web ai percorsi del file system e utilizzare il provider predefinito per tutti i percorsi di cui non si desidera occuparsi.

0

una soluzione molto semplice, soprattutto se si considera la risposta di Scott, sarebbe ad esempio: routes.IgnoreRoute("templates/*.html");, routes.IgnoreRoute("scripts/*.js"); e routes.IgnoreRoute("styles/*.css");.

Questo ti dà sia la semplicità di fornire solo i percorsi a RoutesCollection ed evita il lavoro di dover avviare ad esempio. un VirtualPathProvider.

0

Si potrebbe provare UrlRewiting esempio:

<configuration> 
    <system.webServer> 
    <rewrite> 
     <rules> 
     <rule name="VirtualTourConfig"> 
      <match url="^virtualtour/config.xml" /> 
      <action type="Rewrite" url="virtualtour/config" /> 
     </rule> 
     </rules> 
    </rewrite> 

NB sto usando questo per un diverso caso d'uso (vale a dire che serve un app angolare da asp.net MVC) - Non ho ancora testato se MVC di routing si verifica dopo la riscrittura dell'URL.

Nel mio caso ho un normale percorso MVC (vale a dire /Dashboard/ =>DashboardController.Index()), ma hanno bisogno di tutti i percorsi relativi nel Views/Dashboard/Index.cshtml per servire i file statici senza confondersi con MVC di routing cioè /Dashboard/app/app.module.js deve servire un file statico. Io uso UrlRewriting per mappare /Dashboard/(.+)-/ng/Dashboard/{R:1} come segue:

<configuration> 
    <system.webServer> 
    <rewrite> 
     <rules> 
     <rule name="Dashboard"> 
      <match url="^dashboard/(.+)" /> 
      <action type="Rewrite" url="ng/dashboard/{R:1}" /> 
     </rule> 
     </rules> 
    </rewrite> 
Problemi correlati