2010-01-05 7 views
9

J'ai un SitemapActionResult qui substitue le ActionResult, et fournit un sitemap.xml de SEO quand http://www.sprelle.no/Home/SiteMap est frappé. Jusqu'ici tout va bien. Ce que je voudrais, cependant, est de servir sitemap.xml quand Google visite /sitemap.xml. Pour que cela fonctionne, j'ai besoin d'un itinéraire qui voit "sitemap.xml" et dirige vers/Home/Sitemap. Comment créer ce mappage (dans le tableau Routes)?MVC: comment router /sitemap.xml vers un objet ActionResult?

Répondre

14

Ajouter une carte pour:

routes.MapRoute(
      "Sitemap", 
      "sitemap.xml", 
      new { controller = "Home", action = "SiteMap" } 
      ); 

Notez que les routes, le contrôleur et les options d'action sont codés en dur.

+7

J'ai essayé plus tôt aujourd'hui, mais n'a pas pu le faire fonctionner parce que j'ajouté l'itinéraire _after_ la route par défaut. Il doit être inséré avant l'itinéraire par défaut pour fonctionner. Je vous remercie. – HaakonL

+12

N'oubliez pas d'ajouter runAllManagedModulesForAllRequests = "true" pour la configuration de votre module dans system.webServer, sinon il essayera d'utiliser le gestionnaire staticfile et il retournera un 404 –

+0

@RaulVejar Merci! J'ai fait des recherches sur Internet pendant plus d'une heure et vous êtes la première personne à mentionner les modules. Cela a résolu mon problème. RunAllManagedModulesForAllRequest aura un impact sur vos performances. – ddilsaver

6

Vous pouvez utiliser ceci.

Étape 1. Cartographie de l'extension de fichier à TransferRequestHandler

IIS 7 mode intégré utilise des mappages HTTP Handler quelles combinaisons chemin de point/de verbes à un gestionnaire HTTP. Par exemple, il existe un mappage de gestionnaire par défaut qui pointe path = "*. Axd" verbe = "GET, HEAD, POST, DEBUG" vers le module ISAPI approprié pour la version d'exécution .NET sous laquelle s'exécute le site. Le moyen le plus simple de voir les gestionnaires par défaut sous IIS Express est d'exécuter un site sous IIS Express, cliquez avec le bouton droit sur l'icône IIS Express dans la zone de notification, cliquez sur "afficher toutes les applications" et cliquez sur un site. Le lien applicationhost.config en bas est lié, donc vous pouvez simplement cliquer dessus et il devrait charger dans Visual Studio.

Si vous faites défiler vers le bas, vous verrez qu'il existe un mappage StaticFile catchall pour path="*" verb="*" qui pointe vers StaticFileModule,DefaultDocumentModule,DirectoryListingModule. C'est ce qui gérera votre requête .html si vous ne faites rien. La première étape est donc d'ajouter un gestionnaire dans votre web.config qui pointera *.html demandes au TransferRequestHandler. TransferRequestHandler est le gestionnaire qui prend en charge les URL sans extension que vous avez l'habitude de voir dans les routes MVC, par ex. /store/details/5.

L'ajout d'un mappage de gestionnaire est très simple: il suffit d'ouvrir votre fichier web.config et de l'ajouter au noeud <system.webServer/handlers>.

<add name="HtmlFileHandler" path="*.html" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 

Notez que vous pouvez rendre le chemin plus spécifique si vous le souhaitez. Par exemple, si vous ne vouliez intercepter une demande spécifique, vous pouvez utiliser path = « sample.html »

Étape 2. Configuration de la route

Ensuite, vous aurez besoin d'une nouvelle route. Ouvrez App_Start/RouteConfig.cs et appelez l'RegisterRoutes. Mon complet RegisterRoutes ressemble à ceci:

routes.MapRoute(
     name: "XMLPath", 
     url: "sitemapindex.xml", 
     defaults: new { controller = "Home", action = "Html", page = UrlParameter.Optional } 
    ); 

Étape 3. Route des fichiers existants

qui couvre presque, mais il y a une chose à prendre en charge - demandes primordiales qui correspondent à un fichier existant. Si vous avez un fichier appelé myfile.html, le système de routage ne permettra pas l'exécution de votre route. J'ai oublié à ce sujet, a fini avec une erreur HTTP 500 (débordement de récurrence) et a dû demander de l'aide à Eilon Lipton.

Quoi qu'il en soit, c'est facile à corriger - ajoutez simplement routes.RouteExistingFiles = true à l'enregistrement de votre itinéraire. Mon appel RegisterRoutes terminé ressemble à ceci:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     routes.RouteExistingFiles = true; 

     routes.MapRoute(
      name: "CrazyPants", 
      url: "{page}.html", 
      defaults: new { controller = "Home", action = "Html", page = UrlParameter.Optional } 
     ); 

     routes.MapRoute(
      name: "Default", 
      url: "{controller}/{action}/{id}", 
      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      ); 
    } 

C'est tout.

J'ai testé en ajoutant cette action du contrôleur:

public FileResult Html() 
{ 
    var stringBuilder = new StringBuilder(); 
    stringBuilder.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 
    stringBuilder.AppendLine("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">"); 
    stringBuilder.AppendLine("<sitemap>"); 
    stringBuilder.AppendLine("<loc>http://sprint-newhomes.move.com/sitemaps/sitemap_01.xml</loc>"); 
    stringBuilder.AppendLine("<lastmod>" + DateTime.Now.ToString("MMMM-dd-yyyy HH:mm:ss tt") + "</lastmod>"); 
    stringBuilder.AppendLine("</sitemap>"); 
    stringBuilder.AppendLine("<sitemap>"); 
    stringBuilder.AppendLine("<loc>http://sprint-newhomes.move.com/sitemaps/sitemap_02.xml</loc>"); 
    stringBuilder.AppendLine("<lastmod>" + DateTime.Now.ToString("MMMM-dd-yyyy HH:mm:ss tt") + "</lastmod>"); 
    stringBuilder.AppendLine("</sitemap>"); 
    stringBuilder.AppendLine("</sitemapindex>"); 

    var ms = new MemoryStream(Encoding.ASCII.GetBytes(stringBuilder.ToString())); 



    Response.AppendHeader("Content-Disposition", "inline;filename=sitemapindex.xml"); 
    return new FileStreamResult(ms, "text/xml"); 
} 
+0

Bien que cette réponse soit correcte, il serait préférable d'inclure le code pertinent ici. Les réponses liées à la liaison peuvent devenir incorrectes si le site Web est déplacé ou supprimé. – Jonathan

0

Pour obtenir cela fonctionne, vous devez faire 2 choses:

  1. Instruire le IIS pour permettre la demande de fichiers statiques "/plan du site .xml "pour frapper votre contrôleur. Sinon, IIS contournera votre application et recherchera directement un fichier portant ce nom. Ajoutez la ligne suivante à votre web.config:
<system.webServer> 
    <handlers> 

     <!-- add the following line --> 
     <add name="SitemapXml" path="sitemap.xml" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/> 

    </handlers> 
</system.webServer> 
  1. Placez un itinéraire dans votre application MVC qui correspond à cette demande à un ActionResult (assurez-vous placer avant route par défaut):
routes.MapRoute(
    name: "Sitemap", 
    url: "sitemap.xml", 
    defaults: new { controller = "YourControllerName", action = "YourActionName" } 
);