2011-01-13 15 views
9

Así que tienen una ruta como esta en mi aplicación MVC 3 se ejecuta en IIS 7:MVC enrutamiento cuando un archivo que realmente existe en la ubicación especificada

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

El truco es que realmente existe un archivo en/VirtualTour/config.xml. Parece que la solicitud simplemente devuelve el archivo xml en esa ubicación en lugar de presionar la ruta, que procesa el XML, realiza algunos cambios y devuelve un XmlResult personalizado.

¿Alguna sugerencia sobre cómo puedo decirle a mi aplicación que llegue a la ruta y no al archivo real en caso de que el archivo exista en el disco?

EDIT: Parece que puedo usar en el método routes.RouteExistingFiles = true; RegisterRoutes de Global.asax para decirle a la aplicación de ignorar archivos en el disco. Esto, sin embargo, establece el indicador globalmente y rompe muchas otras solicitudes dentro de la aplicación. Por ejemplo, todavía quiero que las llamadas a /assets/css/site.css devuelvan el archivo CSS sin tener que establecer rutas específicamente para cada activo estático. Entonces, ahora surge la pregunta: ¿hay alguna manera de hacerlo por ruta?

+3

No creo que hay una manera fácil de lograr esto. ¿Por qué no simplemente mueve el archivo estático a la carpeta '~/App_Data'? –

Respuesta

6

Hasta ahora, la mejor respuesta a esto que he encontrado es aplicar globalmente routes.RouteExistingFiles=true y luego ignorar selectivamente las rutas que quiero pasar a archivos existentes como .js, .css, etc. Así que terminé con algo así como esto:

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

Si alguien tiene una mejor solución, me gustaría verla. Prefiero aplicar selectivamente una bandera "RouteExistingFIles" a rutas individuales, pero no sé si hay una manera de hacerlo.

0

No hay solución aquí, solo una idea.

Puede intentar implementar una solución basada en su propio VirtualPathProvider que proporcionará su propia asignación de rutas de web a las rutas del sistema de archivos y usará el proveedor predeterminado para todas las rutas de las que no desea ocuparse.

0

Una solución muy sencilla, desde luego, si se tiene en cuenta la respuesta de Scott, sería por ejemplo: routes.IgnoreRoute("templates/*.html");, routes.IgnoreRoute("scripts/*.js"); y routes.IgnoreRoute("styles/*.css");.

Esto le brinda la simplicidad de simplemente proporcionar rutas a la Recolección de Rutas y evita el trabajo de tener que iniciar, por ejemplo. un VirtualPathProvider.

0

Usted podría intentar UrlRewiting por ejemplo:

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

NB estoy usando esto para un caso de uso diferente (es decir, al servicio de una aplicación angular de asp.net MVC) - I no hemos probado si enrutamiento MVC ocurre DESPUÉS de la reescritura url.

En mi caso tengo una vía normal MVC (es decir /Dashboard/ =>DashboardController.Index()) pero necesitan todas las rutas relativas en el Views/Dashboard/Index.cshtml para servir archivos estáticos sin confundirse por MVC enrutamiento es decir /Dashboard/app/app.module.js debe servir a un archivo estático. Yo uso UrlRewriting para mapear /Dashboard/(.+) a /ng/Dashboard/{R:1} de la siguiente manera:

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