10 votes

Routage MVC lorsqu'un fichier existe réellement à l'emplacement spécifié

J'ai donc une route comme celle-ci dans mon application MVC 3 fonctionnant sous IIS 7 :

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

L'astuce est qu'un fichier existe réellement à l'adresse /virtualtour/config.xml. Il semble que la requête renvoie simplement le fichier xml à cet emplacement au lieu d'atteindre la route, qui traite le XML, effectue quelques modifications et renvoie un XmlResult personnalisé.

Avez-vous des suggestions sur la façon dont je peux dire à mon application de frapper l'itinéraire et non le fichier réel dans le cas où le fichier existe sur le disque ?

EDITAR: Il semble que je puisse utiliser routes.RouteExistingFiles = true; dans la méthode RegisterRoutes de Global.asax pour indiquer à l'application d'ignorer les fichiers sur disque. Cependant, cette méthode définit le drapeau de manière globale et interrompt de nombreuses autres requêtes au sein de l'application. Par exemple, je veux toujours que les appels à /assets/css/site.css renvoient le fichier CSS sans avoir à configurer spécifiquement des routes pour chaque actif statique. La question est donc de savoir s'il existe un moyen de le faire par route.

8voto

Scott Points 5497

Jusqu'à présent, la meilleure réponse que j'ai trouvée à ce problème est d'appliquer globalement routes.RouteExistingFiles=true et ensuite ignorer sélectivement les routes que je veux passer par des fichiers existants comme .js, .css, etc. Je me suis donc retrouvé avec quelque chose comme ça :

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 quelqu'un a une meilleure solution, j'aimerais la voir. Je préférerais de loin appliquer sélectivement un drapeau "RouteExistingFIles" à des itinéraires individuels, mais je ne sais pas s'il existe un moyen de le faire.

0voto

NOtherDev Points 6284

Il ne s'agit pas d'une solution, mais d'une idée.

Vous pouvez essayer de mettre en œuvre une solution basée sur votre propre expérience. VirtualPathProvider qui fournira votre propre correspondance entre les chemins web et les chemins du système de fichiers et utilisera le fournisseur par défaut pour tous les chemins dont vous ne voulez pas vous occuper.

-1voto

Dizzypointed Points 1

Une solution très simple, surtout si l'on tient compte de la réponse de Scott, serait eg : routes.IgnoreRoute("templates/*.html"); , routes.IgnoreRoute("scripts/*.js"); y routes.IgnoreRoute("styles/*.css"); .

Cela permet à la fois de fournir simplement des chemins à la collection de routes et d'éviter de devoir lancer, par exemple, un VirtualPathProvider (fournisseur de chemins virtuels).

-1voto

Ilan Points 125

Vous pouvez essayer UrlRewiting par exemple :

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

NB J'utilise ceci pour un cas d'utilisation différent (i.e. servir une application angulaire depuis asp.net MVC) - je n'ai pas testé si le routage MVC se produit APRES la réécriture de l'url.

Dans mon cas, j'ai une route MVC normale (i.e. /Dashboard/ => DashboardController.Index() ) mais ont besoin de tous les chemins relatifs dans le Views/Dashboard/Index.cshtml pour servir des fichiers statiques sans être dérouté par le routage MVC, c'est à dire /Dashboard/app/app.module.js doit servir un fichier statique. J'utilise UrlRewriting pour mapper /Dashboard/(.+) a /ng/Dashboard/{R:1} comme suit :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X