首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这可以使用ASP.NET URL重写来完成吗?

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

Stack Overflow用户
提问于 2015-04-23 12:45:10
回答 2查看 291关注 0票数 0

我的网站上有大约1700篇文章是用ASP.NET 4.0WebForms创建的。这些文章的网址格式如下:

代码语言:javascript
复制
http://www.mymymyarticles.com/Article.aspx?ID=400

我已经探索了ASP.NET友好的URL以及IIS重写。这些扩展是很棒的,但是一旦创建了规则,它们就会笼统地处理所有url的扩展。

我是否可能手动为我网站上存在的每个url生成我自己的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

因此,您可以看到,在url中没有一致性,我想手动生成。基本上我想要完全控制网址。我该怎么做。会影响性能吗?

任何例子都是值得赞赏的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-30 16:12:49

您有办法将ID映射到新页面的url吗?如果是这样的话,您可能可以通过ASP.NET路由来实现这一点。我要做的是首先定义一条路线:

代码语言:javascript
复制
var route = routes.MapRoute(
    "LegacyDocument",
    "Articles.aspx{*pathInfo}",
    null,
    constraints: new { pathInfo = new LegacyDocumentRouteConstraint() }
);
route.RouteHandler = new RedirectRouteHandler();

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

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

代码语言:javascript
复制
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中存储一个变量,这样我们就可以在稍后的路由处理程序中再次使用它(而不必再从查询字符串中解析它):

代码语言:javascript
复制
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到新的url。

票数 0
EN

Stack Overflow用户

发布于 2015-04-23 14:40:05

我克服了这一问题,在服务器上使用以下模式创建了一个xml文件

代码语言:javascript
复制
<URLMapper>
    <Code>1</Code>
    <OLDURL>%Oldurl.aspx%</OLDURL>
    <NEWURL>default.aspx</NEWURL>
    <PermanentRedirect>true</PermanentRedirect>
    <Order>1</Order>
    <Status>true</Status>
  </URLMapper>

在Application_Start事件中将其加载到应用程序变量(以datatable的形式)。

在开始的请求中--

代码语言:javascript
复制
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;
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29823873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档