C# 在umbraco中重定向URL,如果找不到文档,则重定向到其他位置
我需要从CMS中不存在的文档重定向到现有的文档 我有一个Umbraco安装和旧CMS中的旧链接。我需要将这些旧链接重定向到umbraco中的新结构,但由于每个CMS的结构不同,我需要设置一些规则 我的第一个想法是设置IIS,当它(Umbraco)返回404时,将有另一个内部重定向(如果原始请求符合某些规则)。我想这种方式最终会通过URL重写,但我无法正确设置它C# 在umbraco中重定向URL,如果找不到文档,则重定向到其他位置,c#,asp.net-mvc,iis,http-status-code-404,umbraco,C#,Asp.net Mvc,Iis,Http Status Code 404,Umbraco,我需要从CMS中不存在的文档重定向到现有的文档 我有一个Umbraco安装和旧CMS中的旧链接。我需要将这些旧链接重定向到umbraco中的新结构,但由于每个CMS的结构不同,我需要设置一些规则 我的第一个想法是设置IIS,当它(Umbraco)返回404时,将有另一个内部重定向(如果原始请求符合某些规则)。我想这种方式最终会通过URL重写,但我无法正确设置它 可能有大量页面需要重定向,因此我希望由服务器处理,而不是由应用程序本身处理性能问题。在/Config/umbracoSettings.C
可能有大量页面需要重定向,因此我希望由服务器处理,而不是由应用程序本身处理性能问题。在
/Config/umbracoSettings.Config
中,您可以配置节点来处理所有未找到的页面
<errors>
<!--
<error404>
<errorPage culture="default">nodeId</errorPage>
</error404>
-->
nodeId
只是一个带有模板的常规节点,因此您可以将逻辑放在其中。您可以为错误页面设置文档类型,然后在模板或控制器中处理处理,根据请求URL等重定向到另一个页面。我经常使用它根据请求URL建议相关或类似页面。好的,最后解决方案是创建自定义HTTP模块
public class Redirector : IHttpModule
{
#region --- Private Properties ---
private static Logger logger = LogManager.GetCurrentClassLogger();
private static ConcurrentDictionary<string, string> Dictionary = new ConcurrentDictionary<string, string>();
#endregion
#region --- LifeCycle ---
public void Dispose()
{
}
public void Init(HttpApplication context)
{
logger.Error("RedirectModule: I have been initialized");
FillDictionary();
context.EndRequest += EndHandler;
}
public bool IsReusable
{
get { return true; }
}
private void FillDictionary()
{
logger.Error("Filling dictionary");
try
{
var currentDir = Directory.GetCurrentDirectory();
ResourceManager rm = new ResourceManager("Resources.resx",
Assembly.GetExecutingAssembly());
var text = Resources.DICTIONARY_FILE;
var parsedText = text.Split('\n');
foreach (var row in parsedText)
{
var split = row.Split(';');
if (split == null || split.Length != 2)
{
continue;
}
if(!Dictionary.ContainsKey(split[0]))
{
logger.Trace($"Adding key {split[0]}");
Dictionary.TryAdd(split[0], split[1]);
}
}
}
catch(Exception exception)
{
logger.Error(exception, "Unable to fill dictinary");
}
}
#endregion
#region --- Handlers ---
private void EndHandler(object sender, EventArgs e)
{
logger.Trace("RedirectModule: End of reqest catched");
try
{
HttpApplication application = (HttpApplication)sender;
var code = application.Response.StatusCode;
Exception currentException = application.Server.GetLastError();
HttpException httpException = currentException != null ? (currentException as HttpException) : null;
HttpContext context = application.Context;
if (httpException != null)
{
if (httpException.GetHttpCode() == 404)
{
logger.Trace($"RedirectModule: 404 catched in ending as exception, original path: {context.Request.Url}");
if (Dictionary.ContainsKey(context.Request.Url.ToString()))
{
context.Response.Redirect(Dictionary[context.Request.Url.ToString()]);
logger.Trace($"redirecting to {Dictionary[context.Request.Url.ToString()]}");
}
else
{
logger.Trace($"Dictionary contains no record for {Dictionary[context.Request.Url.ToString()]}");
logger.Trace($"Current amount of keys in dictionary is: {Dictionary.Count}");
}
}
else
{
logger.Error("RedirectModule: Unknown catched as ending");
}
}
else if (code == 404)
{
logger.Trace($"RedirectModule: 404 catched in ending with no exception, original Url: {context.Request.Url}");
if (Dictionary.ContainsKey(context.Request.Url.ToString()))
{
context.Response.Redirect(Dictionary[context.Request.Url.ToString()]);
logger.Trace($"redirecting to {Dictionary[context.Request.Url.ToString()]}");
}
else
{
logger.Trace($"Dictionary contains no record for {Dictionary[context.Request.Url.ToString()]}");
logger.Trace($"Current amount of keys in dictionary is: {Dictionary.Count}");
}
}
else if(code != 200)
{
logger.Trace("Some other error code catched");
}
}
catch (Exception exception)
{
logger.Error(exception, "RedirectModule: Encountered and exception");
}
}
#endregion
}
}
公共类重定向程序:IHttpModule
{
#地区-私人物业---
私有静态记录器Logger=LogManager.GetCurrentClassLogger();
私有静态ConcurrentDictionary=新ConcurrentDictionary();
#端区
#区域-生命周期---
公共空间处置()
{
}
公共void Init(HttpApplication上下文)
{
logger.Error(“重定向模块:我已初始化”);
FillDictionary();
context.EndRequest+=EndHandler;
}
公共布尔可重用
{
获取{return true;}
}
私有void FillDictionary()
{
记录器错误(“填充字典”);
尝试
{
var currentDir=Directory.GetCurrentDirectory();
ResourceManager rm=新的ResourceManager(“Resources.resx”,
Assembly.getExecutionGassembly());
var text=Resources.DICTIONARY\u文件;
var parsedText=text.Split('\n');
foreach(parsedText中的变量行)
{
var split=row.split(“;”);
if(split==null | | split.Length!=2)
{
继续;
}
如果(!Dictionary.ContainsKey(拆分[0]))
{
Trace($“添加键{split[0]}”);
TryAdd(拆分[0],拆分[1]);
}
}
}
捕获(异常)
{
logger.Error(异常,“无法填充字典”);
}
}
#端区
#区域-处理程序---
私有void EndHandler(对象发送方,EventArgs e)
{
logger.Trace(“重定向模块:捕获的请求结束”);
尝试
{
HttpApplication=(HttpApplication)发送方;
var代码=application.Response.StatusCode;
Exception currentException=application.Server.GetLastError();
HttpException HttpException=currentException!=null?(currentException作为HttpException):null;
HttpContext=application.context;
if(httpException!=null)
{
if(httpException.GetHttpCode()==404)
{
Trace($“RedirectModule:404以异常结尾捕获,原始路径:{context.Request.Url}”);
if(Dictionary.ContainsKey(context.Request.Url.ToString())
{
Redirect(Dictionary[context.Request.Url.ToString()]);
Trace($“重定向到{Dictionary[context.Request.Url.ToString()]}”);
}
其他的
{
Trace($”字典不包含{Dictionary[context.Request.Url.ToString()]}的记录);
Trace($“字典中当前的键数为:{dictionary.Count}”);
}
}
其他的
{
logger.Error(“重定向模块:未知捕获为结束”);
}
}
否则如果(代码==404)
{
Trace($“RedirectModule:404在结尾捕获,没有异常,原始Url:{context.Request.Url}”);
if(Dictionary.ContainsKey(context.Request.Url.ToString())
{
Redirect(Dictionary[context.Request.Url.ToString()]);
Trace($“重定向到{Dictionary[context.Request.Url.ToString()]}”);
}
其他的
{
Trace($”字典不包含{Dictionary[context.Request.Url.ToString()]}的记录);
Trace($“字典中当前的键数为:{dictionary.Count}”);
}
}
否则,如果(代码!=200)
{
Trace(“捕获到一些其他错误代码”);
}
}
捕获(异常)
{
logger.Error(异常,“重定向模块:遇到和异常”);
}
}
#端区