C# 在umbraco中重定向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

我需要从CMS中不存在的文档重定向到现有的文档

我有一个Umbraco安装和旧CMS中的旧链接。我需要将这些旧链接重定向到umbraco中的新结构,但由于每个CMS的结构不同,我需要设置一些规则

我的第一个想法是设置IIS,当它(Umbraco)返回404时,将有另一个内部重定向(如果原始请求符合某些规则)。我想这种方式最终会通过URL重写,但我无法正确设置它


可能有大量页面需要重定向,因此我希望由服务器处理,而不是由应用程序本身处理性能问题。

/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(异常,“重定向模块:遇到和异常”);
}
}
#端区