Получение 404 для действия HttpPost

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

В настоящее время, если я нажимаю на запись с идентификатором, вызывается правильный метод действия. Если я выбираю запись без идентификатора (вместо использования уникального идентификатора строки «учетной записи»), я получаю 404.

Конфигурация маршрута:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapMvcAttributeRoutes();
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
}

Частичный вид:

...
<td>
    @if (item.ID != null)
    {
        @Html.ActionLink("Edit", "EditBudget", new { id = item.ID })
    }
    else if (item.Account != null)
    {
        @Html.ActionLink("Edit", "EditAccountBudget", new { account = item.Account })
    }
</td>

БюджетыКонтроллер:

// POST: Budgets/Edit/5
[Route("edit/{id?}")]
[HttpPost]
public ActionResult EditBudget(int? id = null, FormCollection collection = null)
{
    ...
    // Responding correctly for URL: http://localhost:4007/edit/19
}

[Route("editaccountbudget/{account}")]
[HttpPost]
public ActionResult EditAccountBudget(string account)
{
    ...
    // Getting 404 for URL: http://localhost:4007/editaccountbudget/6000..130
}
[Route("budgets/ не совместим с @Html.ActionLink("Edit", наверное.
Giorgos Betsos 15.12.2020 21:23

Обновлено. Все еще получаю 404.

IrishChieftain 15.12.2020 21:26

Попробуйте это [Route("edit/editaccountbudget/{account}")]

Giorgos Betsos 15.12.2020 21:28

Еще 404:localhost: 4007/edit/editaccountbudget/6000..145

IrishChieftain 15.12.2020 22:06

@IrishChieftain: Похоже, вы не используете здесь сообщение. Попробуйте удалить атрибут [HttpPost].

Jackdaw 15.12.2020 23:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
215
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Предполагая, что EditBudget — это имя вашего контроллера, вы можете изменить ваш маршрут к этому, чтобы не запутаться (или оставить как есть, поскольку маршрут атрибута будет проигнорирован) и также удалить [POST] из вашего действия:

[Route("~EditBudget/EditAccountBudget/{account}")]

Также измените:

        @Html.ActionLink("Edit", "EditAccountBudget", new new { account = item.Account })

К:

        @Html.ActionLink("EditAccountBudget", "EditBudget", new { account = item.Account })
   

Если вы используете элементы управления шаблона Razor Pages, вам необходимо иметь как контроллер, так и часть действия маршрута в соответствии с вашим сопоставлением маршрута. Если вы используете ajax или httpclient, у вас может быть любой синтаксис маршрута.

Любопытно, почему атрибут маршрута игнорируется? Первый параметр ActionLink — это текст этой ссылки, так что это ничего не меняет.

IrishChieftain 16.12.2020 15:52

@Html.ActionLink генерирует тег <a> с контроллером и именем действия без маршрутизации.

Serge 16.12.2020 15:56

Вы правы в этом случае, кажется. Но есть возможность передавать маршруты в API, насколько я вижу. Я нашел решение и опубликую ответ.

IrishChieftain 16.12.2020 15:59

ActionLink отображает обычный тег привязки (<a />), поэтому он делает только GET, а не POST. Если вы хотите получить значения POST, вам нужно использовать настоящую форму (либо создать собственный тег, либо использовать Html.BeginForm() ), а затем включить в область действия этой формы кнопку отправки.

+1 на ПОЛУЧИТЬ. Это частичный вид. Ссылка приводит пользователя к форме редактирования, которая будет иметь собственный тег формы.

IrishChieftain 16.12.2020 15:54

@IrishChieftain: Рад, если это поможет. У меня была такая же проблема в моем приложении.

Jackdaw 16.12.2020 16:01

Ваш BudgetsController должен выглядеть, как показано ниже, без атрибута HttpPost и без атрибута маршрута, поскольку вы используете имена методов в ActionLink. Вы можете использовать атрибут HttpGet, если хотите.

Также нет необходимости в параметре коллекции FormCollection в методе EditBudget. Вы ничего не получите, так как это Get not Post.

public ActionResult EditBudget(int? id = null)
{
}

public ActionResult EditAccountBudget(string account)
{
}

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

IrishChieftain 16.12.2020 15:57
Ответ принят как подходящий

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

Частичный вид:

@if (item.ID != null)
{
    @Html.ActionLink("Edit", "EditBudget", new { id = item.ID })
}
else if (item.Account != null)
{
    @Html.ActionLink("Edit", "EditBudget", new { account = item.Account,
        SelectedDepartment = item.SelectedDepartment, SelectedYear = item.SelectedYear })
}

БюджетыКонтроллер:

// GET
public ActionResult EditBudget(int? id, BudgetsViewModel model)
{
    repo = new BudgetDemoRepository();
    if (id != null)
    {
        // Pass id to repository class
    }
    else
    {
        // Pass account and other params to repository class

    }

    return View(...);
}

Другие вопросы по теме