【问题标题】:ASP.NET MVC: Redirect from query string params to a canonical urlASP.NET MVC:从查询字符串参数重定向到规范 url
【发布时间】:2011-04-14 11:11:04
【问题描述】:

在我的 Asp.Net Mvc 项目中,我想要一个好看的 url,例如mysite.com/Page2,并且我想从具有 301 状态的旧样式 url(例如 mysite.com?page=2)重定向,这样就不会有两个具有相同内容的 url。有办法吗?

据我所知,Asp.Net 绑定框架在查询字符串和大括号参数之间没有区别

【问题讨论】:

  • 真正的 ASP.NET 页面是如何命名的?
  • user49223,好吧,我认为这没有意义,但这里有一个例子:/Article/1022/Ms-Sharepoint-Setup-Manual/Page2。这里的第 2 页是用于显示本文的 cmets 的分页。目前这个网址看起来是这样的:/Article/1022/Ms-Sharepoint-Setup-Manual?page=2
  • 我不确定这是否会提供您认为的 SEO 好处。如果只更改页面的 cmets 部分,Page1 和 Page2 上的内容仍然基本相同。
  • Chris Sainty,是的,在这个特定的示例中,这不会提供任何可见的 SEO 利润,我之所以写它是因为它很简单。我同意你可能不想仅仅为了好看的寻呼而改变你的路由系统。但是,如果您有一个像 mysite.com/Articles?category=Sharepoint 这样的网址,您想将其更改为 mysite.com/Articles/Sharepoint 并且如何做到这一点的问题仍然存在

标签: c# asp.net-mvc redirect


【解决方案1】:

我不确定,我没听错你的问题。看来,您当前的设置依赖于那些 GET 参数(如 mysite.com?page=2)。如果您不想更改此设置,则必须进一步使用这些参数。不过,这样做不会有问题。您的用户不必使用或查看它们。为了仅发布“新样式 URL”,您可以在 Web 服务器中设置 URL 重定向。这会将新样式 URL 更改为旧样式 URL。

问题在于 301。如果用户请求旧式 URL,它也会被网络服务器接受。拒绝带有 301 错误的请求对我来说似乎很难实现。

为了解决这个问题,我想你必须改变你的参数方案。您的站点可能仍依赖 GET 参数 - 但它们会获得一个新名称。可以说,您的 cmets 在旧方案中为以下(内部)URL 提供了属性:

/Article/1022/Ms-Sharepoint-Setup-Manual?newpage=2

注意新的参数名称。在您的根页面(或母版页,如果您正在使用它们)中,您可以手动处理永久重定向 (301)。因此,传入的“旧样式请求”可以通过使用旧参数名称来区分。这可用于在 ASP 代码中手动组装响应中的 301。

就个人而言,我建议放弃 301 的想法,而只使用 URL 重定向。

【讨论】:

  • user492238,更改查询字符串参数是个好点,但在母版页中重定向我认为对于 MVC 项目来说不是很好
【解决方案2】:

好吧,据我所知,在 ASP.NET MVC 中执行这种重定向可能会很棘手。我就是这样做的:

global.asax:

        routes.Add(new QueryStringRoute());

        routes.MapRoute(null, "Article/{id}/{name}",
            new { controller = "Article", action = "View", page = 1 },
            new { page = @"\d+" }
        );

        routes.MapRoute(null, "Article/{id}/{name}/Page{page}",
            new { controller = "Article", action = "View" },
            new { page = @"\d+" }
        );

QueryStringRoute.cs:

public class QueryStringRoute : RouteBase
{
    private static string[] queryStringUrls = new string[]
    {
        @"~/Article/\d{1,6}/.*?page=\d{1,3}"
    };


    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        string url = httpContext.Request.AppRelativeCurrentExecutionFilePath;

        foreach (string queryStringUrl in queryStringUrls)
        {
            Regex regex = new Regex(queryStringUrl);
            if (regex.IsMatch(url))
            {
                long id = 0; /* Parse the value from regex match */
                int page = 0; /* Parse the value from regex match */
                string name = ""; /* Parse the value from regex match */

                RouteData rd = new RouteData(this, new MvcRouteHandler());

                rd.Values.Add("controller", "QueryStringUrl");
                rd.Values.Add("action", "Redirect");
                rd.Values.Add("id", id);
                rd.Values.Add("page", page);
                rd.Values.Add("name", name);
                rd.Values.Add("controllerToRedirect", "Article");
                rd.Values.Add("actionToRedirect", "View");

                return rd;
            }
        }

        return null;
    }


    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return null;
    }
}

QueryStringUrlController.cs:

public class QueryStringUrlController : Controller
{
    public RedirectToRouteResult Redirect(long id, int page, string name,
        string controllerToRedirect, string actionToRedirect)
    {
        return RedirectToActionPermanent(actionToRedirect, controllerToRedirect, new { id = id, page = page, name = name });
    }
}

假设您在我的 global.asax 文件(上面列出)中有这样的路由,您可以创建一个自定义的 Route 类来处理传入的请求并将它们映射到一个特殊的重定向控制器上,然后将它们重定向到适当的 url 301 状态。然后您必须将此路由添加到 global.asax 之前您的“文章”路由

【讨论】:

    【解决方案3】:

    如果您使用的是 IIS 7,URL Rewrite Module 应该适用于您的场景。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多