如何正确规范化的ASP.NET MVC应用程序的URL? [英] How to correctly canonicalize a URL in an ASP.NET MVC application?

查看:258
本文介绍了如何正确规范化的ASP.NET MVC应用程序的URL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一个很好的通用方法,规范化的网址在ASP.NET MVC 2应用程序。这是我想出来的,到目前为止:

I'm trying to find a good general purpose way to canonicalize urls in an ASP.NET MVC 2 application. Here's what I've come up with so far:

// Using an authorization filter because it is executed earlier than other filters
public class CanonicalizeAttribute : AuthorizeAttribute
{
    public bool ForceLowerCase { get;set; }

    public CanonicalizeAttribute()
        : base()
    {
        ForceLowerCase = true;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        RouteValueDictionary values = ExtractRouteValues(filterContext);
        string canonicalUrl = new UrlHelper(filterContext.RequestContext).RouteUrl(values);
        if (ForceLowerCase)
            canonicalUrl = canonicalUrl.ToLower();

        if (filterContext.HttpContext.Request.Url.PathAndQuery != canonicalUrl)
            filterContext.Result = new PermanentRedirectResult(canonicalUrl);
    }

    private static RouteValueDictionary ExtractRouteValues(AuthorizationContext filterContext)
    {
        var values = filterContext.RouteData.Values.Union(filterContext.RouteData.DataTokens).ToDictionary(x => x.Key, x => x.Value);
        var queryString = filterContext.HttpContext.Request.QueryString;
        foreach (string key in queryString.Keys)
        {
            if (!values.ContainsKey(key))
                values.Add(key, queryString[key]);
        }
        return new RouteValueDictionary(values);
    }
}

// Redirect result that uses permanent (301) redirect
public class PermanentRedirectResult : RedirectResult
{
    public PermanentRedirectResult(string url) : base(url) { }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.RedirectPermanent(this.Url);
    }
}

现在我可以标记我的控制器是这样的:

Now I can mark up my controllers like this:

[Canonicalize]
public class HomeController : Controller { /* ... */ }

这一切似乎工作得相当好,但我有以下的问题:

This all appears to work fairly well, but I have the following concerns:

  1. 我还是要对 CanonicalizeAttribute 添加到每个控制器(或操作方法)我要规范化,当它是很难想象的情况下,我赢了吨要这种行为。好像应该有一种方式来获得这种行为站点范围内的,而不是一次一个控制器。

  1. I still have to add the CanonicalizeAttribute to every controller (or action method) I want canonicalized, when it's hard to think of a situation where I won't want this behaviour. It seems like there should be a way to get this behaviour site-wide, rather than one controller at a time.

这是我实施武力小写的过滤规则,这一事实似乎是错误的。当然,最好还是以某种方式作用,这件事到路径URL的逻辑,但我不能想办法做到这一点在我的路由配置。我认为加入 @[AZ] *约束控制器和动作参数(以及任何其他字符串路由参数),但我认为这会导致路由不匹配。另外,由于小写规则没有被施加在路径级,这是可能的,以产生在我的网页具有在其中大写字母,这似乎pretty的坏链接

The fact that I'm implementing the 'force to lower-case' rule in the filter seems wrong. Surely it would be better to somehow role this up into the route url logic, but I can't think of a way to do this in my routing configuration. I thought of adding @"[a-z]*" constraints to the controller and action parameters (as well as any other string route parameters), but I think this will cause the routes to not be matched. Also, because the lower-case rule isn't being applied at the route level, it's possible to generate links in my pages that have upper-case letters in them, which seems pretty bad.

有什么明显我俯瞰吗?

推荐答案

我已经感受到了同样的痒关于默认的ASP.NET MVC路由的轻松自然,无视信套管,尾随斜线等你一样,我想一般的解决问题的办法,preferably在我的应用程序的路由逻辑的一部分。

I have felt the same "itch" regarding the relaxed nature of the default ASP.NET MVC routing, ignoring letter casing, trailing slashes, etc. Like you, I wanted a general solution to the problem, preferably as part of the routing logic in my applications.

在网上搜索高和低,没有发现有用的库后,我决定推出一个自己。其结果是。规范化,一个开源类库的ASP.NET路由引擎补充。

After searching the web high and low, finding no useful libraries, I decided to roll one myself. The result is Canonicalize, an open-source class library that complements the ASP.NET routing engine.

您可以通过安装的NuGet库:安装-包。规范化

You can install the library via NuGet: Install-Package Canonicalize

而在你的路线报名: routes.Canonicalize()小写();

此外小写,几个其他的URL规范化策略包括在包中。力 WWW 域$ P $上PFIX或关闭,强制特定的主机名,斜线等,这也是很容易的添加自定义URL标准化战略,我我很开放,接受补丁增加更多的战略,以官的。规范化的分配。

Besides lowercase, several other URL canonicalization strategies are included in the package. Force www domain prefix on or off, force a specific host name, a trailing slash, etc. It is also very easy to add custom URL canonicalization strategies, and I am very open to accept patches adding more strategies to the "official" Canonicalize distribution.

我希望你或其他人会发现这是很有帮助的,即使问题是一岁:)

I hope you or anyone else will find this helpful, even if the question is a year old :)

这篇关于如何正确规范化的ASP.NET MVC应用程序的URL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆