ASP.NET MVC ActionLink: генерируется странный URL-адрес


Почему следующий Html.ActionLink вызов:

Html.ActionLink("Approve", "Advance", new { id = Model.ID, step = StepType.Approve })

Создайте URL-адрес с параметрами запроса, а не" спокойный " URL-адрес, т. е.:

http://localhost/Website/Case/Advance/1?step=Refer

У меня зарегистрирован только маршрут по умолчанию, нужны ли мне дополнительные маршруты, которые могут понять, что такое параметр "StepType"?

Я пытался добавить этот маршрут в после маршрута по умолчанию:

routes.MapRoute(
    "CaseAdvance",
    "{controller}/{action}/{id}/{step}",
    new {controller = "Case", action = "Advance", id = "", step = StepType.Refer});
Но это не возымело никакого действия. Добавление новой регистрации маршрута перед по умолчанию дало мне ошибку:

Словарь параметров содержит нулевая запись для параметра 'id' необнуляемый тип System.Типа int64' для метод ' система.Сеть.В MVC.ActionResult Advance (Int64, Website.Ядро.StepType)' в - Сайт.Контроллеры.CaseController'. Чтобы сделать параметр необязательным его тип должен быть либо ссылочным типом, либо Тип nullable.

4 2

4 ответа:

Пользовательский маршрут слишком много ловит в данный момент

Ваше исключение только говорит вам, что ваш пользовательский маршрут ловит что-то, что вы не собирались ловить. Поэтому, если бы был запрос к корневому URL вашего приложения:

Http://localhost/Website

Ваш пользовательский маршрут поймает его. И установите его по умолчанию. И назовите свое CaseController.Advance() действие. И, конечно, бросьте исключение, потому что id не определено.

Держите пользовательский маршрут перед значением по умолчанию один

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

Но какое изменение вы должны сделать? Если есть только один контроллер, которому это нужно, то измените его на:
routes.MapRoute(
    "CaseAdvance",
    "Case/{action}/{id}/{step}",
    new { controller = "Case", action = "Advance", id = "", step = StepType.Refer});

Если есть другие контроллеры колодца, вы можете сохранить его таким, каким он был, просто добавьте ограничения:

routes.MapRoute(
    "CaseAdvance",
    "{controller}/{action}/{id}/{step}",
    new { controller = "Case", action = "Advance", id = "", step = StepType.Refer},
    new { controller = "Case|Other" });

Если может существовать какой-либо контроллер, вы можете сделать требование, чтобы ваш id был числовое:

routes.MapRoute(
    "CaseAdvance",
    "{controller}/{action}/{id}/{step}",
    new { controller = "Case", action = "Advance", id = "", step = StepType.Refer},
    new { id = @"\d+" })

В этом случае этот маршрут будет перехватывать только те запросы, которые действительно имеют определенный идентификатор. В качестве номера, конечно.

Вы будете знать, какой из них подходит вам больше всего.

Да, если нет маршрута, такого как" {controller}/{action}/{id}/{step}", то метод ActionLink просто передаст" step " в качестве параметра строки запроса.

В вашем маршруте вы указали параметр stepType, но передаете параметр, называемый step.

Имена параметров actionlink должны совпадать с именами параметров маршрута, иначе вы получите именно то, что видите.

EDIT: хорошо, вы изменили свой код, пока я набирал этот ответ!!

Попробуйте использоватьRouteLink и посмотрите, работает ли это для вас.

Html.RouteLink("Approve", "CaseAdvance", new { controller = "Case", action = "Advance", id = Model.ID, step = StepType.Approve })

Если при вызове RouteLink создается допустимая ссылка, это, по крайней мере, будет означать, что ваш маршрут настроен правильно.