Asp.net mvc 3 使用路由更正URL中的键入错误

Asp.net mvc 3 使用路由更正URL中的键入错误,asp.net-mvc-3,routes,Asp.net Mvc 3,Routes,我正在管理一个MVC3应用程序,我需要支持第三方在我的域内创建指向资产的链接。由于一些链接被邮件合并和其他文本编辑问题分割,因此引入了带有拼写错误的URL,例如: /Content/ima!+ges/email/spacer.gif 或 我想先用正则表达式去掉这些无关的字符,然后再尝试为它们服务。我认为这是Route方法可以实现的,我欢迎一两篇演示这种方法的文章 附录(因为我需要格式): 实现@Nathan的路由时,我无法将文件名发送给控制器处理程序-它总是看到传入的空值。我尝试了“filep

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

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

我想先用正则表达式去掉这些无关的字符,然后再尝试为它们服务。我认为这是Route方法可以实现的,我欢迎一两篇演示这种方法的文章

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

实现@Nathan的路由时,我无法将文件名发送给控制器处理程序-它总是看到传入的空值。我尝试了“
filepath
”和“
path
”,结果都是“null”

        routes.MapRoute(
          "MangledFilename",
          "{*filepath}",
          new { controller = "MangledFilename", action = "ServeFile" }
          );
我认为这是在IISExpress上配置通配符处理的问题,我正在分别寻找解决方案。更严重的直接问题是您的建议如何返回HttpNotFound-我得到的是一个硬IIS异常(执行暂停,出现黄色屏幕死亡),而不是静默的404结果

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

thx

我认为这种方法应该可以奏效:

首先,在路线的末尾添加如下路线:

    routes.MapRoute(
      "MangledFilename",
      "{*filepath}",
      new { controller = "MangledFilename", action = "ServeFile" });
如果您以前没有见过它们,那么在打开
{
之后带有
*
的路由参数是一个通配符参数,在这种情况下,它将匹配整个路径。如果您想将此行为限制在
内容
目录中,也可以像
内容/{*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/内容类型,您可以选择使用预期提供的硬编码类型,或者使用本文中详细介绍的解决方案之一:

编辑:

经过思考,我意识到有另一种方法可以处理
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 Anderson提供了一个很好的答案,但它似乎不完整

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

String sourcestring = "source string to match with pattern";
String matchpattern = @"[+!]";
String replacementpattern = @"";
Console.WriteLine(Regex.Replace(sourcestring,matchpattern,replacementpattern));
从该工具生成此代码


这是您需要的代码。此代码还将从文件名中删除任何+字符。如果您不希望出现这种行为,您可以选择一个不带文件名的子字符串,并且只替换文件名前的+和!字符。

谢谢Nathan-我认为返回HttpNotFound()的代码位有问题”-我编辑的问题中的详细信息appreciated@justSteve,那么,为什么不将其投票并将其标记为正确答案,以便其他人能够更快地找到它?这很有帮助,但不是问题的真正意义?如何处理后续问题?
String sourcestring = "source string to match with pattern";
String matchpattern = @"[+!]";
String replacementpattern = @"";
Console.WriteLine(Regex.Replace(sourcestring,matchpattern,replacementpattern));