url路由到小写如何?

时间:2011-12-25 07:39:07

标签: asp.net-mvc asp.net-mvc-3


我在asp.net mvc3上开发了一个Web应用程序,现在我需要创建路径,小写的 例如:

 that's what i have:
 http://www.example.com/SubFolder/Category/Index => looks ugly :-)

 that's how i would like it:
 http://www.example.com/subfolder/category/index

我找到了这个帖子:
http://goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc/

我实际上需要使用页面底部的global.asax中的代码。

protected void Application_BeginRequest(Object sender, EventArgs e)   
{
    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();
    }
}

现在的问题是:
什么时候在开发站上使用它的工作是完美的,但是当我上传它到生产它不起作用。

在开发站上,它只发布,但在制作时它会做两个:

POST - status: 301 Moved Permanently 
GET  - status: 200 OK

我根本没有被重定向到正确的路线。 在开发站上它完美无缺。

4 个答案:

答案 0 :(得分:4)

protected void Application_BeginRequest(Object sender, EventArgs e)
{
    string lowercaseURL = (Request.Url.Scheme + 
    "://" +
    HttpContext.Current.Request.Url.Authority +
    HttpContext.Current.Request.Url.AbsolutePath);
    if (Regex.IsMatch(lowercaseURL, @"[A-Z]"))
    {
        System.Web.HttpContext.Current.Response.RedirectPermanent
        (
             lowercaseURL.ToLower() + HttpContext.Current.Request.Url.Query
        );
    }
}

答案 1 :(得分:2)

由于您使用的是ASP.NET MVC,我不认为Application_BeginRequest是可行的方法。 MVC提供了更好的选项来处理这些要求。

也可以使用IIS Url Rewrite模块(Web.config配置)来实现,但我认为您更喜欢更具编程性的方法。

尝试使用ActionFilter代替:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class EnforceLowercaseUrlAttribute : ActionFilterAttribute
{
    private bool _redirect;

    public EnforceLowercaseUrlAttribute(bool redirect = true)
    {
        this._redirect = redirect;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var request = filterContext.HttpContext.Request;
        var path = request.Url.AbsolutePath;
        var containsUpperCase = path.Any(char.IsUpper);

        if (!containsUpperCase || request.HttpMethod.ToUpper() != "GET")
            return;

        if (this._redirect)
            filterContext.Result = new RedirectResult(path.ToLowerInvariant(), true);

        filterContext.Result = new HttpNotFoundResult();
    }
}

然后将其应用于Controller / Action:

[EnforceLowercaseUrl]
public ActionResult Index()
{
     ....
}

或在Global.asax

中全局注册
GlobalFilters.Filters.Add(new EnforceLowercaseUrlAttribute());

答案 2 :(得分:2)

如果这只是针对SEO,最简单的解决方案和我将使用的是使用url重写(假设你在IIS上托管)或mod重写(如果你在Apache上托管)来强制执行小写网址并离开这些帖子就是这样。

使用IIS,就像从Web平台安装程序安装url rewrite一样简单,点击添加规则并选择“强制使用小写URL”。容易。

如果您升级到mvc4并且真的想要小写帖子,那么有一个属性LowercaseUrls,您可以在注册路由时将其设置为true。但同样 - 我不会打扰。

答案 3 :(得分:0)

我是这样做的,我创建了一个自定义路线。这也使Html.ActionLink之类的助手也创建了操纵路线。

首先,我使用自定义对象Route扩展LowerCaseRoute并覆盖GetVirtualPath方法,如下所示:

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
    var path = base.GetVirtualPath(requestContext, values);
    if (path != null)
    {
        // you could do lots more here, like replacing odd characters with - etc.
        path.VirtualPath = path.VirtualPath.ToLower();
    }
    return path;
}

然后我创建一个自定义助手来映射这条路线:

public static LowerCaseRoute MapLowerCaseRoute(this RouteCollection routes, string name, string url, object defaults)
{
    var route = new LowerCaseRoute(url, new MvcRouteHandler());
    route.Defaults = new RouteValueDictionary(defaults);
    route.DataTokens = new RouteValueDictionary();
    route.DataTokens.Add("RouteName", name);
    routes.Add(name, route);
    return route;
}

这样您就可以在global.asax中创建一条路线,如下所示:

RouteTable.Routes.MapLowerCaseRoute("routeName", "baseurl/someother/{param}", { controller = "Controller", param = UrlParameter.Optional });

这样可以使项目内的所有内容保持整洁,并为您提供更多操作路线的选项。