umbraco中的URL重定向,如果找不到文档,则重定向到其他地方

时间:2019-06-14 14:05:06

标签: c# asp.net-mvc iis http-status-code-404 umbraco

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

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

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

可能会有大量的页面需要重定向,所以我希望这可以由服务器来处理,而不是由于性能问题而由应用本身来处理。

3 个答案:

答案 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)向我指出了这个方向。