asp.net core post метод, помощники тегов и строка запроса

Я получаю это неожиданное поведение от ядра asp.net, которое я начинаю изучать.

В моем представлении есть форма ниже:

<form asp-controller="Account" asp-action="Login" method="post">
    <button type="submit">LOGIN</button>
</form>

Да, я использую здесь помощники тегов. А вот и контроллер:

public class AccountController : Controller
{
    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> Login(string returnUrl)
    {
        if (string.IsNullOrEmpty(returnUrl) || !Url.IsLocalUrl(returnUrl))
                    return RedirectToAction("index", "home");
                else
                    return LocalRedirect(returnUrl);
    }

}

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

<form method="post">
    <button type="submit">LOGIN</button>
</form>

а потом начинает работать. Но почему там такое поведение, что вызывает это, почему помощники тегов формы не позволяют привязать строку запроса для этой формы метода публикации ???


person yogi    schedule 24.10.2019    source источник


Ответы (2)


Если вы используете форму по умолчанию без помощника тега, она по умолчанию получит строку запроса.

Если вы используете помощник тега для указания контроллера и действия, ваш код будет преобразован в:

<form method="post" action="/Account/Login">

Это привело к тому, что returnUrl всегда был нулевым.

Чтобы получить returnUrl, вам нужно указать маршрут, используя asp-route-{value}, как показано ниже, иначе он попадет в шаблон маршрута по умолчанию:

<form asp-controller="Account" asp-action="Login" asp-route-returnUrl="yourUrl" method="post">
<button type="submit">LOGIN</button>
</form>

Это означало бы:

<form method="post" action="/Account/Login?returnUrl=yourUrl">

Ссылка:

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/anchor-tag-helper?view=aspnetcore-3.0#asp-route-value

person Rena    schedule 25.10.2019

Вы выполняете запрос POST, поэтому связыватель модели пытается получить параметры из тела запроса.

Вы можете добавить поле в форму:

<form asp-controller="Account" asp-action="Login" method="post">
    <input type="hidden" name="returnUrl" value="http://some_url" />
    <button type="submit">LOGIN</button>
</form>

Или, если вы хотите выполнить запрос POST и по-прежнему получить параметр returnUrl из строки запроса, вам необходимо указать связывателю модели сделать это с помощью атрибута FromQuery:

[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login([FromQuery(Name = "returnUrl")] string returnUrl)
{
    if (string.IsNullOrEmpty(returnUrl) || !Url.IsLocalUrl(returnUrl))
                return RedirectToAction("index", "home");
            else
                return LocalRedirect(returnUrl);
}

Изменить

В вашем последнем примере вы просто используете стандартный HTML-код без какого-либо помощника ASP.NET, поэтому URL-адрес с параметром отправляется так, как он есть, на сервер, то есть без какой-либо обработки фреймворком, и, таким образом, он анализируется правильно, но это может перестать работать если вы измените имя своего действия публикации, если у вас есть несколько действий публикации в вашем контроллере или если у вас определены более сложные маршруты.

person Isma    schedule 24.10.2019
comment
спасибо за ответ, попробую. Однако он все еще не отвечает, почему просто удаление помощников тегов и сохранение публикации метода формы решает проблему. Если это вызвано только методом method = post, как вы предлагаете, то даже после удаления помощников тегов он не должен работать. - person yogi; 25.10.2019
comment
Я бы не сказал, что это решает проблему, это просто скрывает ее; Я добавил комментарий по этому поводу. - person Isma; 25.10.2019