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

时间:2015-04-23 12:45:11

标签: asp.net url-rewriting url-routing

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

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

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

我是否有可能为我网站上的每个网址手动生成自己的网址字符串?例如:

我希望将http://www.mymymyarticles.com/Article.aspx?ID=400永久重定向到http://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

所以你可以看到我想手动生成的网址没有统一性。基本上我想完全控制网址。我怎么能这样做呢。 会影响效果吗?

感谢任何例子。

2 个答案:

答案 0 :(得分:0)

我通过使用以下架构

在服务器上创建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 Event中的这个加载到应用程序变量中(以数据表的形式)。

并在Begin Request -

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;
        }

答案 1 :(得分:0)

您是否有办法将ID映射到新页面的网址?如果是这种情况,您可以使用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处理程序。您需要找到解决实际新网址(ResolveNewDocumentUrl)的位置,但通常会解析网址,如果网址返回为null,我们将发出{{ 1}}回复说客户(更重要的是抓取工具)项目不再存在,或者它会向新网址发出带有相应位置标头的HTTP 410 Gone