47 votes

faire des URL en minuscule. Tout moyen facile ou intégré?

Existe-t-il un moyen simple / intégré de créer une URL en minuscule pour MVC3?

J'ai un code qui pourrait le faire, mais cherchant quelque chose de simple à implémenter.

  routes.MapRouteLowercase(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "index", id = UrlParameter.Optional } // Parameter defaults
            );

public class LowercaseRoute : 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 Route MapRouteLowercase(this RouteCollection routes, string name, string url)
        {
            return routes.MapRouteLowercase(name, url, null /* defaults */, (object)null /* constraints */);
        }

        public static Route MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults)
        {
            return routes.MapRouteLowercase(name, url, defaults, (object)null /* constraints */);
        }

        public static Route MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults, object constraints)
        {
            return routes.MapRouteLowercase(name, url, defaults, constraints, null /* namespaces */);
        }

        public static Route MapRouteLowercase(this RouteCollection routes, string name, string url, string[] namespaces)
        {
            return routes.MapRouteLowercase(name, url, null /* defaults */, null /* constraints */, namespaces);
        }

        public static Route MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults, string[] namespaces)
        {
            return routes.MapRouteLowercase(name, url, defaults, null /* constraints */, namespaces);
        }

        public static Route MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
        {
            if (routes == null)
            {
                throw new ArgumentNullException("routes");
            }
            if (url == null)
            {
                throw new ArgumentNullException("url");
            }

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

            if ((namespaces != null) && (namespaces.Length > 0))
            {
                route.DataTokens["Namespaces"] = namespaces;
            }

            routes.Add(name, route);

            return route;
        }

        public static Route MapRouteLowercase(this AreaRegistrationContext context, string name, string url)
        {
            return context.MapRouteLowercase(name, url, (object)null /* defaults */);
        }

        public static Route MapRouteLowercase(this AreaRegistrationContext context, string name, string url, object defaults)
        {
            return context.MapRouteLowercase(name, url, defaults, (object)null /* constraints */);
        }

        public static Route MapRouteLowercase(this AreaRegistrationContext context, string name, string url, object defaults, object constraints)
        {
            return context.MapRouteLowercase(name, url, defaults, constraints, null /* namespaces */);
        }

        public static Route MapRouteLowercase(this AreaRegistrationContext context, string name, string url, string[] namespaces)
        {
            return context.MapRouteLowercase(name, url, (object)null /* defaults */, namespaces);
        }

        public static Route MapRouteLowercase(this AreaRegistrationContext context, string name, string url, object defaults, string[] namespaces)
        {
            return context.MapRouteLowercase(name, url, defaults, null /* constraints */, namespaces);
        }

        public static Route MapRouteLowercase(this AreaRegistrationContext context, string name, string url, object defaults, object constraints, string[] namespaces)
        {
            if (namespaces == null && context.Namespaces != null)
            {
                namespaces = context.Namespaces.ToArray();
            }

            Route route = context.Routes.MapRouteLowercase(name, url, defaults, constraints, namespaces);
            route.DataTokens["area"] = context.AreaName;

            // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
            // controllers belonging to other areas
            bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0);
            route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;

            return route;
        }
    }
 

99voto

krolik Points 2573

Je viens de remarquer qu'il existe une nouvelle propriété dans .NET Framework 4.5. Fonctionne très bien! RouteCollection.LowercaseUrls

Définissez LowercaseUrls sur true

 public static void RegisterRoutes(RouteCollection routes)
{
    routes.LowercaseUrls = true;
    ...
}
 

Créer un lien

 @Html.ActionLink("Log in", "Login", "Account")
 

Cela va créer une URL géniale et minuscule :)

 <a href="http://stackoverflow.com/account/login">Log in</a>
 

17voto

Victor H. Ponce Points 381

Il existe un package NuGet pour cela: LowerCaseRoutesMVC ( site web du projet )

12voto

Jeremy Points 826

Si vos raisons pour l'application de la minuscule est purement SEO, alors la meilleure solution que j'ai trouvé est d'utiliser IIS 7 Module de Réécriture d'URL

Non seulement vous avez la capacité de forcer tous les url en minuscules, mais vous avez également accès à des règles qui vous permettent de supprimer/ajouter des barres obliques, appliquer canonique domaines etc.

RuslanY Blog a un bon ensemble pour commencer à partir. Par exemple, j'utilise la suite sur l'ensemble de mes sites:

<!-- http://ruslany.net/2009/04/10-url-rewriting-tips-and-tricks/ -->
<rule name="Convert to lower case" stopProcessing="true">
    <match url=".*[A-Z].*" ignoreCase="false" />
    <conditions>
        <add input="{REQUEST_METHOD}" matchType="Pattern" pattern="GET" ignoreCase="false" />
    </conditions>
    <action type="Redirect" url="{ToLower:{R:0}}" redirectType="Permanent" />
</rule>

Il suffit d'ajouter les lignes ci-dessus la section de votre site web.config.

1voto

Keith Points 3403

Oui, j'ai dû mettre en œuvre quelque chose de similaire à ce qui précède. Cela semble être le seul moyen sans heurts d'y parvenir.

Je voudrais ajouter qu’en outre, nous avons ajouté 301 redirections afin que tout le trafic provenant de / Upper-Case-Url soit 301 redirigé vers / upper-case-url.

1voto

Chase Florell Points 18248

Vous ne savez pas ce qui ne va pas avec votre code (le mien est un peu différent, mais correspond essentiellement au même concept). C'est très facile à mettre en œuvre et entièrement réutilisable.

LowerCaseRouteHelper.cs

 using System.Web.Routing;
using System.Web.Mvc;

namespace Utilities.Helpers
{
    public class LowercaseRouteHelper : System.Web.Routing.Route
    {
        public LowercaseRouteHelper(string url, IRouteHandler routeHandler) : base(url, routeHandler)
        {
        }
        public LowercaseRouteHelper(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler)
        {
        }
        public LowercaseRouteHelper(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler) : base(url, defaults, constraints, routeHandler)
        {
        }
        public LowercaseRouteHelper(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
    {
        [System.Runtime.CompilerServices.Extension()]
        public static void MapRouteLowercase(RouteCollection routes, string name, string url, object defaults)
        {
            routes.MapRouteLowercase(name, url, defaults, null);
        }

        [System.Runtime.CompilerServices.Extension()]
        public static void MapRouteLowercase(RouteCollection routes, string name, string url, object defaults, object constraints)
        {
            if (routes == null) {
                throw new ArgumentNullException("routes");
            }

            if (url == null) {
                throw new ArgumentNullException("url");
            }

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

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

global

 routes.MapRouteLowercase("Start", "", new {
    controller = "Home",
    action = "Index"
})
 

J'adore cela, et le point positif (comme l'indiquent les commentaires) est que cela aide vraiment à améliorer le référencement.

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