使用.NET MVC路由中的正则表达式来处理大写字符

时间:2010-07-22 18:48:27

标签: .net regex model-view-controller routes global-asax

我正在研究.NET MVC应用程序,并尝试在global.asax.cs中编写路由。目标是,我希望任何包含大写字符的URL都可以通过所述路由运行。这个想法是,路由器将小写URL并重定向它。我的方法是使用正则表达式来处理这个问题。这就是我所拥有的:

routes.MapRoute(
    "CanonicalizationRoute", 
    "{*url}", 
    new 
    { 
        controller = "CanonicalRouter", 
        action = "Reroute" 
    }, 
    new 
    { 
        url = @"[A-Z]+" 
    });

似乎没有做到这一点......有关如何最好地处理这个的任何想法?

2 个答案:

答案 0 :(得分:0)

如果您只是想支持小写路由(基本上使您的路由不区分大小写),您可以查看以下内容。我们目前正在使用它,效果很好。

首先,您将需要一个RouteExtensions.cs文件,或使用以下内容命名您喜欢的任何内容(与ASP.NET MVC RC1兼容):

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

namespace MyMvcApplication.App.Helpers
{
    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)
        {
            if (routes == null)
                throw new ArgumentNullException("routes");

            if (url == null)
                throw new ArgumentNullException("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);
        }
    }
}

然后在Global.asax.cs文件中使用引用到上面的类,并且你们都设置为创建一个小写路由。 您可以在下面看到一个小写路由示例,只要这个路由被调用,您的URL就会小写。

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

并且可选地,如果您有兴趣将任何传入的URL转换为小写(由用户手动键入或称为链接),您可以在Application_BeginRequest()方法中使用它(请记住,小写路由本身不需要这个,代码以上将处理):

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        // If upper case letters are found in the URL, redirect to lower case URL.
        // Was receiving undesirable results here as my QueryString was also being converted to lowercase.
        // You may want this, but I did not.
        //if (Regex.IsMatch(HttpContext.Current.Request.Url.ToString(), @"[A-Z]") == true)
        //{
        //    string LowercaseURL = HttpContext.Current.Request.Url.ToString().ToLower();

        //    Response.Clear();
        //    Response.Status = "301 Moved Permanently";
        //    Response.AddHeader("Location", LowercaseURL);
        //    Response.End();
        //}

        // If upper case letters are found in the URL, redirect to lower case URL (keep querystring the same).
        string lowercaseURL = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
        if (Regex.IsMatch(lowercaseURL, @"[A-Z]"))
        {
            lowercaseURL = lowercaseURL.ToLower() + HttpContext.Current.Request.Url.Query;

            Response.Clear();
            Response.Status = "301 Moved Permanently";
            Response.AddHeader("Location", lowercaseURL);
            Response.End();
        }
    }

答案最初来自this SO帖子。

此答案的内容来自一篇不再可用的博客文章,但可以在archive.org here上查看。

答案 1 :(得分:-1)

你有没有机会运行IIS 7? URL Rewrite模块提供了一种在应用程序外部处理此方法的好方法(在web.config文件中配置)。 Here's a blog post about it,包括您的具体需求。

未经测试,但至于您的代码问题,正则表达式是否需要允许除大写字母之外的字符? “* [A-Z] +。*”