【问题标题】:Using Routes to correct typos in a URL使用路由更正 URL 中的拼写错误
【发布时间】:2012-03-09 21:25:04
【问题描述】:

我正在管理一个 MVC3 应用程序,我需要支持第 3 方在我的域中创建指向资产的链接的能力。由于某些链接因邮件合并和其他文本编辑问题而被切片和切块,因此引入了拼写错误的 URL,例如:

/Content/ima!+ges/email/spacer.gif

/Content/image++s/email+/spacer.gif

在尝试为它们提供服务之前,我想通过 RegEx 去除这些无关字符。我_认为这是一个 Route 方法可以完成的事情,我欢迎提供一两篇文章来演示这种方法。

附录(因为我需要格式化):

实现@Nathan 的路由我无法将文件名发送到控制器处理程序 - 它总是看到传入的 null 值。我已经尝试使用相同的 'null' 和 'filepath' 和 'path' ' 结果。

        routes.MapRoute(
          "MangledFilename",
          "{*filepath}",
          new { controller = "MangledFilename", action = "ServeFile" }
          );

我认为这是在 IISExpress 上配置通配符处理的问题,我正在单独寻找该解决方案。更严重的直接问题是您的建议如何返回 HttpNotFound - 我得到一个硬 IIS 异常(执行停止并出现 YellowScreenDeath),而不是无声的 404 结果。

    public ActionResult ServeFile(string filePath)
    {
        if (filePath != null) // workaround the null
        {
               ...
        }
        return HttpNotFound();
    }

谢谢

【问题讨论】:

    标签: asp.net-mvc-3 routes


    【解决方案1】:

    我认为这种方法应该可行:

    首先在路由注册声明的末尾添加这样的路由:

        routes.MapRoute(
          "MangledFilename",
          "{*filepath}",
          new { controller = "MangledFilename", action = "ServeFile" });
    

    如果您以前没有见过它们,那么在开头{ 之后带有* 的路由参数是通配符参数,在这种情况下它将匹配整个路径。如果您想将此行为限制在您的 content 目录中,您也可以将其写为 content/{*filepath}

    然后像这样的控制器应该可以解决问题:

        public class MangledFilenameController : Controller
        {
            public ActionResult ServeFile(string filePath)
            {
                filePath = CleanFilePath(filePath);
                var absolutePath = Server.MapPath(filePath);
    
                if (System.IO.File.Exists(absolutePath))
                {
                    var extension = System.IO.Path.GetExtension(absolutePath);
                    var contentType = GetContentTypeForExtenion(extension);
                    return File(absolutePath, contentType);
                }
    
                return HttpNotFound();
            }
    
            private string CleanFilePath(string filepath)
            {
                //clean the path up
                return filepath;
            }
    
            private string GetContentTypeForExtenion(string extension)
            {
                //you will want code here to map extensions to content types
                return "image/gif";
            }
        }
    

    关于将扩展映射到 GetContentTypeForExtension 方法的 MIME / 内容类型,您可以选择硬编码您期望提供的类型,或使用本文中详述的解决方案之一:

    File extensions and MIME Types in .NET

    编辑:

    经过思考,我意识到还有另一种方法可以处理ServeFile 操作。重定向到现有文件可能更简单。我将保留上面写的原始方法,并在此处添加替代方法:

        public ActionResult ServeFile(string filePath)
        {
            filePath = CleanFilePath(filePath);
            var absolutePath = Server.MapPath(filePath);
    
            if (System.IO.File.Exists(absolutePath))
            {
                return RedirectPermanent(filePath);
            }
    
            return HttpNotFound();
        }
    

    【讨论】:

    • 谢谢 Nathan - 我认为你'return HttpNotFound();'的代码有问题- 我编辑的问题中的详细信息。 - 赞赏
    【解决方案2】:

    我相信@Nathan Anderson 提供了一个很好的答案,但似乎不完整。

    如果您想更正拼写错误并且类型与您提到的一样简单,那么您可以使用 Nathan 代码,但在尝试查找文件之前,您可以删除路径中的所有加号或感叹号字符,您就可以做到像这样:

    String sourcestring = "source string to match with pattern";
    String matchpattern = @"[+!]";
    String replacementpattern = @"";
    Console.WriteLine(Regex.Replace(sourcestring,matchpattern,replacementpattern));
    

    My Regex Tester 工具生成此代码。

    这是您需要的代码。此代码还会从文件名中删除任何 + 字符。如果你不想要这种行为,你可以选择一个没有文件名的子字符串,只替换 + 和 !文件名前的字符。

    【讨论】:

    • @justSteve,那么为什么不点赞并将其标记为正确答案,以便其他人可以更快地得到它?
    • 有帮助但不是问题的真正重点是什么?后续如何处理?
    猜你喜欢
    • 2014-01-06
    • 2012-01-09
    • 2012-09-09
    • 2017-10-14
    • 2023-02-11
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    相关资源
    最近更新 更多