Note: the answer may be in either VB.NET or C#. I have no preference for this Q&A.
I'm following this example to build a simple ASP.NET Core 8 MVC application that uses cookie authentication. I'm running into a problem where the query string on the URL isn't being sent to the controller. The value for Request.QueryString
is an empty string.
Here's my URL:
https://localhost:55387/Account/SignIn?ReturnUrl=%2FContacts
Here's my controller:
Public Class AccountController
<HttpPost>
Public Async Function SignInAsync(Setting As Setting) As Task(Of IActionResult)
Dim ReturnUrl As String = Me.Request.Query("ReturnUrl")
' etc.
End Function
End Class
...and here's my view:
@model Db.Models.Setting
@{
ViewData["Title"] = "Sign In";
}
<h1>Sign In</h1>
<h4>Enter the site PIN</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="SignIn">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group col-5">
<label asp-for="AuthPin" class="control-label"></label>
<input id="authPin" asp-for="AuthPin" class="form-control" />
<span asp-validation-for="AuthPin" class="text-danger"></span>
</div>
<div class="form-group">
<input id="signInButton" type="submit" class="btn btn-primary" value="Sign In" disabled />
</div>
</form>
</div>
</div>
The trouble is that the example is for a Razor Pages application. Mine is MVC. In the example, this works just fine:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
this.ReturnUrl = returnUrl;
}
Here, the returnURL
variable is populated as expected. But in MVC, we don't have an OnPostAsync
function. I'm handling everything in the controller action. And the action isn't picking up the query string for some reason.
There's this answer, but in my case there is no Url
property on the Request
instance. There is a Path
property, but its value doesn't contain a query string ("/Account/SignIn").
There's also this answer, but adding a ReturnUrl
parameter on the SignIn
post action didn't help.
How can I get my controller/action to collect the query string on form POST
?
I was able to work around the problem using this technique. It's not the prettiest solution, but it works at least.
In the view:
@Html.Hidden("QueryString", @Context.Request.QueryString)
...and then in the controller:
<HttpPost>
Public Async Function SignInAsync(QueryString As String) As Task(Of IActionResult)
Dim oQueryString As NameValueCollection
Dim oDictionary As RouteValueDictionary
Dim sReturnUrl As String
Dim oResult As IActionResult
oQueryString = HttpUtility.ParseQueryString(QueryString)
oDictionary = New RouteValueDictionary
sReturnUrl = oQueryString("ReturnUrl")
Array.ForEach(oQueryString.AllKeys, Sub(Key) oDictionary.Add(Key, oQueryString(Key)))
oResult = Me.RedirectToAction("SignIn", oDictionary)
' etc.
End Function
That did the trick.