Asp.Net MVC - лучший подход для «динамической» маршрутизации - PullRequest
10 голосов
/ 22 декабря 2008

Я пытаюсь придумать подход для создания «динамической» маршрутизации. Что я имею в виду, так это то, что я хочу иметь возможность назначать контроллер и действие маршрута для каждого попадания, а не отображать его напрямую.

Например, маршрут может выглядеть как этот «путь / {объект}», и когда этот путь будет достигнут, выполняется поиск, предоставляющий соответствующий контроллер / действие для вызова.

Я пытался найти механизмы для создания собственного обработчика маршрута, но документация / обнаруживаемость в настоящее время немного неясны (я знаю, это бета-версия - я бы больше не ожидал). Хотя я не уверен, что это даже лучший подход и, возможно, фабрика контроллеров или даже контроллер / действие по умолчанию, которое выполняет все сопоставления, может быть лучшим маршрутом (без каламбура).

Любой совет будет оценен.

1 Ответ

3 голосов
/ 14 июля 2011

Вы всегда можете использовать синтаксис перехвата всех (я понятия не имею, правильное ли имя).

Маршрут: routeTable.MapRoute( "Path", "{*path}", new { controller = "Pages", action = "Path" });

Действие контроллера определяется как: public ActionResult Path(string path)

В действии для контроллера у вас будет путь, так что вам нужно просто пролить его и проанализировать.

Для вызова другого контроллера вы можете использовать RedirectToAction (я думаю, что это более правильный путь). С помощью перенаправления вы можете настроить постоянное перенаправление для него. Или используйте что-то подобное:

 internal class MVCTransferResult : RedirectResult
    {
        public MVCTransferResult(string url) : base(url) 
        {
        }
        public MVCTransferResult(object routeValues) 
                : base(GetRouteURL(routeValues))
        {
        }

        private static string GetRouteURL(object routeValues)
        {
            UrlHelper url = new UrlHelper(
                new RequestContext(
                        new HttpContextWrapper(HttpContext.Current),
                        new RouteData()),
                        RouteTable.Routes);
            return url.RouteUrl(routeValues);
        }

        public override void ExecuteResult(ControllerContext context)
        {
            var httpContext = HttpContext.Current;

            // ASP.NET MVC 3.0
            if (context.Controller.TempData != null &&
                context.Controller.TempData.Count() > 0)
            {
                throw new ApplicationException(
                     "TempData won't work with Server.TransferRequest!");
            }
            // change to false to pass query string parameters 
            // if you have already processed them
            httpContext.Server.TransferRequest(Url, true);

            // ASP.NET MVC 2.0
            //httpContext.RewritePath(Url, false);
            //IHttpHandler httpHandler = new MvcHttpHandler();
            //httpHandler.ProcessRequest(HttpContext.Current);
        }
    }

Однако этот метод требует запуска на IIS, или IIS Expres Casinni не поддерживает метод Server.Transfer

...