MVC2, почему распознается только мой первый маршрут? - PullRequest
0 голосов
/ 13 февраля 2012

Итак, сейчас у меня есть два маршрута:

routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

           routes.MapRoute(
               "Legos",
               "{controller}/{action}/{page}",
               new { controller = "Legos", action = "Lego", page = UrlParameter.Optional });

Если я перейду на www.website.com, я смогу видеть мою домашнюю страницу просто отлично, но мой маршрут Legos не работает.Аналогично, если я поставлю свой маршрут Legos сверху, я могу просто перейти на www.website.com/Legos/Lego/1, но при переходе на www.website.com выдается ошибка (ниже), и мне нужно вручную перейти на www.website.com/Home/Indexчтобы увидеть мою домашнюю страницу.

Ошибка:

The parameters dictionary contains a null entry for parameter 'page' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Errors(Int32, System.String)' in 'stuff.Controllers.Legos'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters

С чего бы это?

1 Ответ

1 голос
/ 15 февраля 2012

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

Если вы правильно различаете маршруты, это сработает. Например, вы можете попробовать удалить необязательный параметр «id» из маршрута «По умолчанию» и сделать обязательной часть «страницы» маршрута «Legos» (так как кажется, что она необходима для работы конечной точки, это лучше всего все равно тренируйтесь):

routes.MapRoute(
    "Legos",
    "{controller}/{action}/{page}",
    new { controller = "Legos", action = "Lego", page = 1 });

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}", // URL with parameters
    new { controller = "Home", action = "Index" } // Parameter defaults
);

Это будет означать, что URL с двумя параметрами (т. Е. Home / Index) не будет соответствовать маршруту "Legos", так как в нем отсутствует обязательный параметр "page" - тогда он будет тестировать маршрут "Default", который будет успешно, так как «Home / Index» соответствует ожидаемому формату «{что-нибудь} / {что-нибудь}».

Другой вариант - добавить ограничение маршрута к одному из маршрутов - например, вы можете сделать так, чтобы «страница» принимала только числа, поэтому, если входящий запрос выглядит как {что угодно} / {что угодно} / {числовое}, то это будет соответствовать маршруту "Legos", но если он будет не числовым, он не будет соответствовать ограничению и вместо этого попадет на маршрут по умолчанию:

routes.MapRoute(
"Legos",
url: "{controller}/{action}/{page}",
defaults: new { controller = "Legos", action = "Lego" },
constraints: new { page = @"([0-9]+)" } ); // constrain to "one or more numbers" - constraints are simply regular expressions

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

Конечно, "проблема" с этим конкретным решением была бы, если бы у вас был числовой идентификатор (который, как ни странно, большинство), который вы хотели бы использовать для маршрута "по умолчанию", он в конечном итоге был бы пойман Маршрут "Легос" ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...