我需要从CMS中不存在的文档重定向到现有文档
我有一个Umbraco安装和旧CMS中的旧链接。我需要将这些旧链接重定向到umbraco中的新结构,但是由于每个CMS的结构都不相同,因此我需要设置某种规则。
我的第一个想法是设置IIS,以便当它(Umbraco)返回404时,将进行另一个内部重定向(如果原始请求符合某些规则)。我想该方法最终将通过URL重写进行,但是我无法正确设置它。
可能会有大量的页面需要重定向,所以我希望这可以由服务器来处理,而不是由于性能问题而由应用本身来处理。
答案 0 :(得分:0)
在/Config/umbracoSettings.config
中,您可以配置将处理所有未找到页面的节点
<errors>
<!--
<error404>
<errorPage culture="default">nodeId</errorPage>
</error404>
-->
nodeId
只是模板的常规节点,因此您可以在其中放置逻辑。
答案 1 :(得分:0)
您可以为“错误”页面设置文档类型,然后在模板或Controller中进行处理,根据请求URL等重定向到另一个页面。我经常根据此建议来建议相关或相似的页面请求网址。
答案 2 :(得分:0)
好,最后解决方案是创建自定义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
}
}
它从资源文件获取设置,并重定向到请求的页面。唯一的挫折是我没有设法为重定向设置创建自定义设置xml,因此每次设置更改时都需要重新编译它(enyone知道如何做吗?httpmodule的起始位置使其很难加载任何表单文件)。
我感谢罗伯特·福斯特(Robert Foster)向我指出了这个方向。