简体   繁体   中英

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

I'm getting this unexpected behavior from asp.net core which I'm starting to learn.

I have a below form in my View:

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

Yes I'm using tag helpers here. And here is the controller:

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);
    }

}

Now as per my understanding thus far, returnUrl should automatically get query string value if it is there in query string. But with this setup it is not happening. After a lot of head scratching I found a solution online to change in my view into this:

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

and then it starts working. But why is this behavior there, what is causing this, why form tag helpers not letting query string to bind for this post method form???

You are doing a POST request so the model binder tries to get the parameters from the body of the request.

You could add the field to the form:

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

Or if you want to do a POST request and still get the returnUrl parameter from the query string then you need to instruct the model binder to do so using the FromQuery attribute:

[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);
}

Edit

In your last example you are just using standard HTML code without any ASP.NET helper so the URL with the parameter is sent as it is to the server, ie without any processing by the framework and thus it gets parsed correctly but this may stop working if you change your post action name, if you have several post actions in your controller or if you have more complex routes defined.

If you use default form without tag helper,it would get the query string by default.

If you use tag helper to specify the controller and action,your code would translate into:

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

This caused that returnUrl always be null.

For getting the returnUrl,you need to specify the route by using asp-route-{value} like below,otherwise,it would get into the default route templete:

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

This would translate into:

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

Reference:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM