【问题标题】:asp.net core post method, tag helpers and query stringasp.net 核心发布方法、标签助手和查询字符串
【发布时间】:2020-02-20 13:06:00
【问题描述】:

我正在从我开始学习的 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 方法表单???

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core asp.net-core-tag-helpers


    【解决方案1】:

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

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

    <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

    【讨论】:

      【解决方案2】:

      您正在执行 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);
      }
      

      编辑

      在您的最后一个示例中,您只是使用没有任何 ASP.NET 帮助程序的标准 HTML 代码,因此带有参数的 URL 按原样发送到服务器,即没有框架进行任何处理,因此它被正确解析,但这如果您更改发布操作名称、控制器中有多个发布操作或定义了更复杂的路由,则可能会停止工作。

      【讨论】:

      • 感谢您的回复,我会试试这个。然而,它仍然没有回答为什么仅仅删除标签助手和保留表单方法帖子就可以解决问题。如果它只是像您建议的那样是由 method="post" 引起的,那么即使在删除标签助手之后它也不应该起作用。
      • 我不会说它解决了问题,它只是隐藏了它;我对此添加了评论。
      猜你喜欢
      • 2019-11-13
      • 2019-02-17
      • 2018-06-11
      • 2020-05-16
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      • 2017-05-08
      相关资源
      最近更新 更多