使用路由更正URL中的拼写错误

时间:2012-02-19 01:37:14

标签: asp.net-mvc-3 routes

我正在管理一个MVC3应用,我需要支持第三方创建域内资产链接的能力。由于某些链接是通过邮件合并和其他文本编辑问题进行切片和切块的,因此引入了带有拼写错误的URL,例如:

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

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

在尝试提供服务之前,我想通过RegEx删除这些无关的字符。我认为这是Route方法可以完成的事情,我欢迎一两个指针来展示这种方法。

ADDENDUM(因为我需要格式化):

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

        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();
    }

THX

2 个答案:

答案 0 :(得分:0)

我认为这种方法应该有用:

首先将这样的路线添加到路线注册声明的末尾:

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

如果您之前没有看过它们,则在打开*之后带有{的路径参数是通配符参数,在这种情况下,它将匹配整个路径。如果您想将此行为限制在content/{*filepath}目录,也可以像content一样编写它。

然后像这样的控制器可以做到这一点:

    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();
    }

答案 1 :(得分:0)

我相信@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工具生成此代码。

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