asp.net 核心 post 方法、标签助手和查询字符串

asp.net core post method, tag helpers and query string

我从我开始学习的 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>

然后它开始工作。但是为什么会有这种行为,是什么原因造成的,为什么表单标签助手不允许查询字符串绑定到这个 post 方法表单???

您正在执行 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 将按原样发送到服务器,即没有任何由框架处理,因此它被正确解析,但如果您更改 post 操作名称,如果您的控制器中有多个 post 操作,或者如果您定义了更复杂的路由,这可能会停止工作。

如果你使用没有标签助手的默认表单,它会默认获取查询字符串。

如果您使用标签助手来指定控制器和操作,您的代码将转化为:

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

这导致 returnUrl 始终为 null。

为了获取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