MVC 3 использует разные контроллеры в зависимости от параметров запроса - PullRequest
1 голос
/ 26 августа 2011

Последние пару дней я искал в Интернете решение для этого, и я не нахожу много. Надеюсь, я не использую правильную терминологию, и это легко сделать.

Я хотел бы использовать путь как:

/{projectId}

И есть место где-то в начале жизненного цикла, где у меня есть доступ к словарю значений маршрута, по которому я могу запросить базу данных или объект сеанса, чтобы получить имя контроллера для использования в этом запросе. Затем можно указать контроллер для использования route.Values["controller"] = controllerName; и сделать запрос через этот контроллер со всеми джазом параметров запроса и т. П.

Возможно ли это?

В настоящее время я использую области, и у меня есть такие пути:

/ProjectType1/{projectId}
/ProjectType2/{projectId}

но я считаю, что это настоящая головная боль - иметь дело с областями во всех Html.Link и не люблю определять новые области для каждого типа проекта. Я хотел бы найти что-то более динамичное.

1 Ответ

7 голосов
/ 26 августа 2011

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

public class MyRoute : Route
{
    public MyRoute(string url, IRouteHandler routeHandler)
        : base(url, routeHandler)
    { }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var rd = base.GetRouteData(httpContext);
        var projectId = rd.GetRequiredString("projectId");

        // TODO: Given the projectId decide which controller to choose:
        // you could query the database or whatever it is needed here

        if (projectId == "1")
        {
            rd.Values["controller"] = "Foo";
        }
        else if (id == "2")
        {
            rd.Values["controller"] = "Bar";
        }
        else if (id == "3")
        {
            rd.Values["controller"] = "Baz";
        }
        else
        {
            // unknown project id
            throw new HttpException(404, "Not found");
        }

        // we will always be using the Index action but this could
        // also be variable based on the projectId
        rd.Values["action"] = "index";

        return rd;
    }
}

и зарегистрировать его:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.Add(new MyRoute("{projectId}", new MvcRouteHandler()));
}

Сейчас:

  • /1 вызовет FooController/Index
  • /2 вызовет BarController/Index
  • /3 вызовет BazController/Index
  • /something_else сгенерирует 404 Не найдено
...