Как мне сопоставить URL, начинающийся с буквального символа тильды (~) в System.Web.Routing / ASP.NET MVC? - PullRequest
0 голосов
/ 17 июля 2011

Я конвертирую код старой школы в ASP.NET MVC и столкнулся с проблемой, вызванной нашими форматами URL. Мы задаем ширину, высоту и т. Д. В URL-адресе, добавляя к тильде префикс специального URL-адреса, как в следующем примере:

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

В настоящее время это решается с помощью специального обработчика 404 в IIS, но теперь я хочу заменить /photo/ на ASP.NET и использовать System.Web.Routing для извлечения ширины, высоты и т. Д. Из входящего URL .

Проблема в том, что я не могу сделать это:

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

, поскольку System.Web.Routing не позволяет маршруту начинаться с символа тильды (~).

Изменение формата URL не возможно ... мы публично поддерживали этот формат URL с 2000 года, и в Интернете, вероятно, существует множество ссылок на него. Могу ли я добавить какой-нибудь ограниченный шаблон к маршруту?

1 Ответ

0 голосов
/ 17 июля 2011

Вы можете написать собственный маршрут обрезки:

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
)
{
    ...
}
...