这可以使用 ASP.NET URL 重写来完成吗

Can this be done using ASP.NET URL Rewriting

我的网站上列出了大约 1700 篇使用 ASP.NET 4.0 Web 表单创建的文章。这些文章的 url 格式为:

http://www.mymymyarticles.com/Article.aspx?ID=400

我探索了 ASP.NET 友好 URL 以及 IIS URL 重写。这些扩展很棒,但是一旦创建了规则,它们就会对所有 url 进行通用处理。

是否可以为我网站上存在的每个 url 手动生成自己的 url 字符串?例如:

我想永久重定向 http://www.mymymyarticles.com/Article.aspx?ID=400http://www.mymymyarticles.com/this-is-a-very-long-url

http://www.mymymyarticles.com/Article.aspx?ID=500 可以重定向到 http://www.mymymyarticles.com/article/short-url

http://www.mymymyarticles.com/Article.aspx?ID=523 可以重定向到 http://www.mymymyarticles.com/very-short-url

所以您可以看到我想手动生成的 url 中没有统一性。基本上我想完全控制 url。我该怎么做。 会不会影响性能?

欢迎提供任何示例。

我通过在服务器上使用以下架构创建 xml 文件克服了这个问题

<URLMapper>
    <Code>1</Code>
    <OLDURL>%Oldurl.aspx%</OLDURL>
    <NEWURL>default.aspx</NEWURL>
    <PermanentRedirect>true</PermanentRedirect>
    <Order>1</Order>
    <Status>true</Status>
  </URLMapper>

在 Application_Start 事件中将此加载到应用程序变量(以数据表的形式)。

并在开始请求中 --

void Application_BeginRequest(object sender, EventArgs e)
        {            
            if (Application["URLMapper"] == null) return;
            DataTable dtURLs = Application["URLMapper"] as DataTable;

            if (dtURLs.Rows.Count == 0) return;

            string OrigUrl = HttpContext.Current.Request.Url.ToString().ToLower().Replace("'", "`");

            DataRow[] drFound = dtURLs.Select("Status = true and '" + OrigUrl.Trim() + "' like oldurl", "Order",DataViewRowState.CurrentRows);
            if (drFound.Length == 0) return;
            string OldURL = drFound[0]["OldURL"].ToString().Replace("%","");

            Response.RedirectPermanent(OrigUrl.Replace(OldURL, drFound[0]["NewURL"].ToString().Trim()), true);

            return;
        }

您有办法将 ID 映射到新页面的 url 吗?如果是这种情况,您可能可以使用 ASP.NET 路由来实现此目的。我要做的是从定义路线开始:

var route = routes.MapRoute(
    "LegacyDocument",
    "Articles.aspx{*pathInfo}",
    null,
    constraints: new { pathInfo = new LegacyDocumentRouteConstraint() }
);
route.RouteHandler = new RedirectRouteHandler();

此路由仅捕获对 /articles.aspx 的任何请求,但它具有约束和自定义路由处理程序。

约束的目的是确保我们至少有 ID 查询字符串 属性 并且它是一个数字:

public class LegacyDocumentRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.UrlGeneration)
        {
            // Don't both doing anything while we generate links.
            return false;
        }

        string id = httpContext.Request.QueryString["id"];
        if (string.IsNullOrWhiteSpace(id))
        {
            // No query string argument was provided.
            return false;
        }

        int documentId;
        if (!int.TryParse(id, out documentId))
        {
            // The Id is not a number.
            return false;
        }

        // Set the output document Id in the route values.
        values["documentId"] = documentId;
        return true;
    }
}

如果未提供 ID 或者不是数字,我们将无法匹配现有文档,因此将跳过路由。但是当满足约束时,我们在路由值 values["documentId"] = documentId 中存储一个变量,这样我们就可以稍后在路由处理程序中再次使用它(无需再次从查询字符串中解析它):

public class RedirectRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext context)
    {
        int documentId = (int)context.RouteData.Values["documentId"];

        return new RedirectLegacyDocumentHttpHandler(documentId);
    }

    private class RedirectLegacyDocumentHttpHandler : IHttpHandler
    {
        private int _documentId;

        public RedirectHttpHandler(int documentId)
        {
            _documentId = documentId;
        }

        public bool IsReusable { get { return false; } }

        public void ProcessRequest(HttpContext context)
        {
            var response = context.Response;

            string url = ResolveNewDocumentUrl();
            if (url == null)
            {
                // Issue a 410 to say the document is no longer available?
                response.StatusCode = 410;
            }
            else 
            {
                // Issue a 301 to the new location.
                response.RedirectPermanent(url);
            }
        }

        public string ResolveNewDocumentUrl()
        {
            // Resolve to a new url using _documentId
        }
    }
}

路由处理程序执行从 ASP.NET 路由映射回 ASP.NET 运行时的 IHttpHandler 逻辑的逻辑。在普通的 MVC 中,这将映射到调用控制器的标准 MvcHandler,但在我们的例子中,我们只需要发出重定向。

在路由处理程序中,我们从路由值中获取文档 ID,并创建一个新的 HTTP 处理程序来执行实际的重定向。您需要深入了解实际的新 url 是什么 (ResolveNewDocumentUrl),但通常它会解析 url,如果 url返回为 null,我们将发出 HTTP 410 Gone 响应以告诉客户端(更重要的是爬虫)该项目不再存在,或者它会发出 HTTP 301 Permanent Redirect 适当的位置 header 到新的 url.