【问题标题】:URL redirect in umbraco, when document not found, redirect elsewhereumbraco 中的 URL 重定向,当找不到文档时,重定向到别处
【发布时间】:2019-10-29 04:30:39
【问题描述】:

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

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

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

可能有数百个页面需要重定向,所以我希望由服务器而不是由应用程序本身来处理性能问题。

【问题讨论】:

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


    【解决方案1】:

    /Config/umbracoSettings.config 中,您可以配置节点来处理所有未找到的页面

    <errors>
    <!--
        <error404>
            <errorPage culture="default">nodeId</errorPage>
        </error404>
    -->
    

    nodeId 只是一个带有模板的常规节点,因此您可以将逻辑放入其中。

    【讨论】:

    • 是的,我知道,我将它用于通用 404 页面。问题是当我得到 404 时,我需要通过一些规则表检查文档并重定向到不同的节点。据我所知,此配置不允许根据请求路由到不同的节点。
    【解决方案2】:

    您可以为错误页面设置文档类型,然后在模板或控制器中处理处理,根据请求 URL 重定向到另一个页面等。我经常使用它来根据请求网址。

    【讨论】:

    • 你在umbraco的错误节点中解决路由?这是选项之一,但我希望由 IIS 处理,而不是由 umbraco 本身处理。
    • 您也可以编写一个 HttpModule 或挂钩到 OWIN 来执行此操作。
    • 感谢您的提示,这可能是我要尝试的方式。我将尝试连接到错误处理程序。
    【解决方案3】:

    好的,最后解决方案是创建自定义 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,因此每次设置更改时都需要重新编译(有没有人知道该怎么做?httpmodule的起始位置使得很难加载任何表单文件)。

    感谢 Robert Foster 为我指明了这个方向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-08
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      相关资源
      最近更新 更多