如何在System.Web.Routing / ASP.NET MVC中匹配以文字波形符(〜)开头的URL?

时间:2011-07-17 10:11:15

标签: asp.net-mvc routing asp.net-mvc-routing system.web.routing

我正在将一些旧式代码转换为ASP.NET MVC,并且遇到了由我们的URL格式引起的障碍。我们在URL中指定缩略图宽度,高度等,方法是在特殊URL路径前加上波浪号,如下例所示:

http://www.mysite.com/photo/~200x400/crop/some_photo.jpg

目前,这是由IIS中的自定义404处理程序解决的,但现在我想用ASP.NET替换/photo/并使用System.Web.Routing来提取宽度,高度等。来自传入的URL。

问题是 - 我不能这样做:

routes.MapRoute(
  "ThumbnailWithFullFilename",
  "~{width}x{height}/{fileNameWithoutExtension}.{extension}",
  new { controller = "Photo", action = "Thumbnail" }
);

因为System.Web.Routing不允许路径以波浪号(〜)字符开头。

更改网址格式不是一种选择...我们自2000年以来就公开支持这种网址格式,网络可能会引用它。我可以在路线中添加某种约束通配符吗?

1 个答案:

答案 0 :(得分:0)

您可以编写自定义裁剪路线:

public class CropRoute : Route
{
    private static readonly string RoutePattern = "{size}/crop/{fileNameWithoutExtension}.{extension}";
    private static readonly string SizePattern = @"^\~(?<width>[0-9]+)x(?<height>[0-9]+)$";
    private static readonly Regex SizeRegex = new Regex(SizePattern, RegexOptions.Compiled);

    public CropRoute(RouteValueDictionary defaults)
        : base(
            RoutePattern,
            defaults,
            new RouteValueDictionary(new
            {
                size = SizePattern
            }),
            new MvcRouteHandler()
        )
    {
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var rd = base.GetRouteData(httpContext);
        if (rd == null)
        {
            return null;
        }
        var size = rd.Values["size"] as string;
        if (size != null)
        {
            var match = SizeRegex.Match(size);
            rd.Values["width"] = match.Groups["width"].Value;
            rd.Values["height"] = match.Groups["height"].Value;
        }
        return rd;
    }
}

你会这样注册:

routes.Add(
    new CropRoute(
        new RouteValueDictionary(new
        {
            controller = "Photo",
            action = "Thumbnail"
        })
    )
);

Thumbnail控制器的Photo操作内,您应该在请求/~200x400/crop/some_photo.jpg时获得所需的一切:

public ActionResult Thumbnail(
    string fileNameWithoutExtension, 
    string extension, 
    string width, 
    string height
)
{
    ...
}