2010-12-03 31 views
1

J'essaie de m'assurer que toutes les URL utilisées pour accéder à mon site ASP.NET MVC sont en minuscules. Dans le cas où une lettre majuscule est dans l'URL, je change le code d'état 301 et changer l'emplacement de la version minuscule de l'URL avec ce code:Comment puis-je m'assurer des URL minuscules sur le POST?

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    var url = Request.Url.ToString(); 
    if (Regex.IsMatch(url, @"[A-Z]")) 
    { 
     Response.Clear(); 
     Response.Status = "301 Moved Permanently"; 
     Response.StatusCode = (int)HttpStatusCode.MovedPermanently; 
     Response.AddHeader("Location", url.ToLower()); 
     Response.End(); 
    } 
} 

Cependant, récemment co worker essayait de POSTER un formulaire à une URL avec une lettre majuscule (en oubliant la redirection), mais l'action (marquée avec un attribut HttpPost) n'était pas touchée. En regardant les demandes dans Firebug a montré le POST original, mais alors il a retourné 301 et a émis un GET à la version minuscule.

Je suppose que la meilleure solution est de simplement vous assurer que tous les messages sont à la version minuscule de l'URL, mais je suis venu ici pour voir s'il y a une autre façon de traiter cette question

Répondre

1

Voici une version basée sur la solution de scottm qui fonctionne avec .NET 4.0

protected void Application_BeginRequest(object sender, EventArgs e) { 
    string url = Request.Url.ToString(); 
    if (Request.HttpMethod == "GET" && Regex.Match(url, "[A-Z]").Success) { 
     Response.RedirectPermanent(url.ToLower(), true); 
    } 
} 
0

Par ma compréhension, il n'y a aucun moyen de forcer un utilisateur à réémettre une demande POST. Vous pouvez seulement les rediriger, et cela ne spécifie qu'une URL (pas de données POST). La plus grande question pour moi est: pourquoi vous êtes si catégorique de ne pas avoir des URL majuscules? HTTP spécifie que les URL sont insensibles à la casse.

+1

urls majuscules et minuscules sont considérés comme différents urls par les moteurs de recherche – hunter

+0

Qu'est-ce que chasseur. Ceci est uniquement à des fins SEO http://www.searchenginejournal.com/url-capitalization-and-seo/12667/ – scottm

+0

S'il vous plaît gardez à l'esprit que les moteurs de recherche ne suivent pas POST, mais seulement obtenir des verbes. –

3

Vous pouvez créer une méthode d'extension pour le routage qui rend tout le minuscule d'url:

Le code:

public class LowercaseRoute : System.Web.Routing.Route 
    { 
     public LowercaseRoute(string url, IRouteHandler routeHandler) : base(url, routeHandler) { } 
     public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler) { } 
     public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler) : base(url, defaults, constraints, routeHandler) { } 
     public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler) : base(url, defaults, constraints, dataTokens, routeHandler) { } 

     public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
     { 
      VirtualPathData path = base.GetVirtualPath(requestContext, values); 

      if (path != null) 
       path.VirtualPath = path.VirtualPath.ToLowerInvariant(); 

      return path; 
     } 
    } 

    public static class RouteCollectionExtensions 
    { 
     public static void MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults) 
     { 
      routes.MapRouteLowercase(name, url, defaults, null); 
     } 

     public static void MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults, object constraints) 
     { 
      Check.Argument.IsNotNull(routes, "routs"); 
      Check.Argument.IsNotNull(url, "url"); 

      var route = new LowercaseRoute(url, new MvcRouteHandler()) 
      { 
       Defaults = new RouteValueDictionary(defaults), 
       Constraints = new RouteValueDictionary(constraints) 
      }; 

      if (String.IsNullOrEmpty(name)) 
       routes.Add(route); 
      else 
       routes.Add(name, route); 
     } 
    } 

Votre itinéraire:

routes.MapRouteLowercase(
       "Default", 
       "{controller}/{action}/{id}", 
       new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      ); 

Maintenant, quand vous utilisez le ... Html.BeginForm() ... il va afficher une URL en minuscule pour l'action. Cela affichera également toujours des urls en minuscules chaque fois que vous utiliserez le routage pour afficher un lien, c'est-à-dire Url.Action(); <%: Html.RenderAction()%>

1

Comme le soulignait Giuseppe, les moteurs de recherche n'indexent pas les pages POST. J'ai fini avec ceci:

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    if(Request.HttpMethod == "POST") return; 

    //etc 
} 
0

Développant @bingles grande réponse, peut-être vous ne voulez pas forcer GET données à minuscule? Ensuite, vous voulez utiliser l'expression régulière (?<=^[^?]*)[A-Z] à la place:

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    string url = Request.Url.ToString(); 
    if (Request.HttpMethod == "GET" && Regex.Match(url, "(?<=^[^?]*)[A-Z]").Success) 
    { 
      Response.RedirectPermanent(url.ToLower(), true); 
    } 
} 

Regex pris de cette autre réponse: regex to match all uppercase letters before the first question mark