404 - Открытый метод действия X не найден на контроллере Y (ActionInvoker.InvokeAction возвращает false)
Это не дублирующий вопрос, и проблема сводит меня с ума. Я получаю типичную ошибку "Открытый метод действия X не найден на контроллере Y", который возвращает 404 Not Found
. Снимок экрана дает вам хорошую идею:
![Visual Studio debugging session]()
На изображении показано, что отладчик приостановлен до того, как строка, которая генерирует исключение, выполнена (base.HandleUnknownAction(actionName)
). Теперь, прежде чем вы переходите к выводам, здесь немного информации:
- Это отлично работает в какой-то момент.
- HTTP-глагол (
GET
) должен быть принят действием UpdateCart
(см. аннотации выше подписи метода).
- Отправленные параметры не имеют значения: ошибка происходит с
POST
, GET
и любой комбинацией параметров.
- Другие аналогичные действия в одном контроллере работают хорошо.
- Я снял скриншот с
UpdateCart
с пометкой virtual
, но удаление virtual
не имеет значения.
- Снимок экрана показывает, что
ActionInvoker.InvokeAction(this.ControllerContext, "UpdateCart")
возвращает false. Не уверен, почему отражение, выполненное над моим контроллером, не может найти метод, но оно ПРАВОЕ ТЕБЕ!!
Маршруты являются стандартными, и они работают, поскольку в противном случае я бы не смог остановить отладчик, чтобы снять снимок экрана выше. Здесь код из Global.asax.cs
:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Tickets", action = "Index", id = UrlParameter.Optional }
);
}
Любые идеи приветствуются.
ИЗМЕНИТЬ
Этан Браун отвечает правильно: HttpGet
и HttpPost
являются взаимоисключающими. Решение заключалось в замене этих атрибутов на [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
.
Ответы
Ответ 1
Проблема заключается в том, что вы указываете атрибуты HttpGet
и HttpPost
. Если вы оставите их обоих, действие примет как запросы POST, так и GET. Я предполагаю, что атрибуты HttpGet
и HttpPost
не сообщают MVC, чтобы разрешить соответствующий тип запроса, но запретить противоположный тип. Таким образом, включив [HttpPost]
, вы отказываетесь от запросов GET и включаете [HttpGet]
, вы отказываетесь от запросов POST... фактически отрицая все типы запросов. Оставьте атрибуты выключенными, и он примет оба типа.
Обновление. Я только что проверил источник MVC, и мое предположение верно. В ActionMethodSelector
он проверяет атрибуты таким образом:
if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo))) {
matchesWithSelectionAttributes.Add(methodInfo);
}
Другими словами, все ActionMethodSelectorAttribute
(из которых HttpPostAttribute
и HttpGetAttribute
выводятся) должны возвращать значение true для вызываемого действия. Тот или другой всегда будет возвращать false, поэтому действие никогда не будет выполнено.
Ответ 2
Остерегайтесь: в моем случае я получал ошибку 500 при попытке найти новый метод действий.
IIS 8.5 Подробная ошибка - 500.0 - Общедоступный метод "getwells" не найден на контроллере 'ITVizion.VizionLogs.Widgets.Controllers.MapController'.
Я добавил метод действия к контроллеру и "развернул" обновленное приложение для IIS.
Проблема: я развертывал конфигурацию Debug
в Visual Studio и не контролировал создание этого конкретного проекта. Это было ускорение строительства в Visual Studio, поскольку в решении есть много проектов.: D Переход к папке приложения IIS показал, что DLL проекта устарела.
Поэтому убедитесь, что вы проверяете проект на Build.:) Это, очевидно, позаботится о развертывании нового кодаза в IIS.
![enter image description here]()