我的网站上有大约1700篇文章是用ASP.NET 4.0WebForms创建的。这些文章的网址格式如下:
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中没有一致性,我想手动生成。基本上我想要完全控制网址。我该怎么做。会影响性能吗?
任何例子都是值得赞赏的。
发布于 2015-04-30 16:12:49
您有办法将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到新的url。
发布于 2015-04-23 14:40:05
我克服了这一问题,在服务器上使用以下模式创建了一个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事件中将其加载到应用程序变量(以datatable的形式)。
在开始的请求中--
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;
}https://stackoverflow.com/questions/29823873
复制相似问题