Reading parameters from the URL query string is one of the most common tasks in web development. This guide covers how to do it across different versions of ASP.NET, with a focus on the common login redirect scenario where you need to read the ReturnUrl parameter.
The Problem
When ASP.NET’s authentication system redirects an unauthenticated user to the login page, it automatically appends the original URL as a query string parameter:
https://yoursite.com/Login.aspx?ReturnUrl=/Dashboard
After successful authentication, you need to read that ReturnUrl parameter and redirect the user back to where they were going.
ASP.NET Web Forms (Classic)
Reading a Query String Parameter
// URL: /Login.aspx?ReturnUrl=/Dashboard
string returnUrl = Request.QueryString["ReturnUrl"];
if (!string.IsNullOrEmpty(returnUrl))
{
Response.Redirect(returnUrl);
}
else
{
Response.Redirect("~/Default.aspx");
}
Reading Multiple Parameters
// URL: /Search.aspx?q=mysql+tables&page=2&sort=date
string query = Request.QueryString["q"]; // "mysql tables"
string page = Request.QueryString["page"]; // "2"
string sort = Request.QueryString["sort"]; // "date"
Safely Parsing Numeric Parameters
// Always use TryParse for numeric values
int page = 1; // default
if (int.TryParse(Request.QueryString["page"], out int parsedPage))
{
page = parsedPage;
}
Full Login Page Example
protected void LoginButton_Click(object sender, EventArgs e)
{
if (Membership.ValidateUser(UsernameTextBox.Text, PasswordTextBox.Text))
{
FormsAuthentication.SetAuthCookie(UsernameTextBox.Text, RememberMeCheckBox.Checked);
string returnUrl = Request.QueryString["ReturnUrl"];
if (!string.IsNullOrEmpty(returnUrl) && IsLocalUrl(returnUrl))
{
Response.Redirect(returnUrl);
}
else
{
Response.Redirect("~/Default.aspx");
}
}
else
{
ErrorLabel.Text = "Invalid username or password.";
}
}
// Security: Prevent open redirect attacks
private bool IsLocalUrl(string url)
{
return !string.IsNullOrEmpty(url)
&& (url.StartsWith("/") && !url.StartsWith("//") && !url.StartsWith("/\\"));
}
ASP.NET MVC
Reading from the Controller
public ActionResult Login(string returnUrl)
{
// ASP.NET MVC automatically binds query string parameters to action parameters
ViewBag.ReturnUrl = returnUrl;
return View();
}
[HttpPost]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
// ... validate credentials ...
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
return View(model);
}
Reading Any Query String Parameter
public ActionResult Search()
{
string query = Request.QueryString["q"];
int page = int.TryParse(Request.QueryString["page"], out int p) ? p : 1;
// Or using the ValueProvider (preferred in MVC):
string sort = RouteData.Values["sort"]?.ToString()
?? Request.QueryString["sort"]
?? "relevance";
return View();
}
ASP.NET Core (Modern)
Model Binding (Preferred)
ASP.NET Core automatically binds query string parameters to action method parameters:
// URL: /api/products?category=electronics&page=2&pageSize=20
[HttpGet]
public IActionResult GetProducts(
[FromQuery] string category,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 10)
{
// Parameters are automatically bound and typed
var products = _service.GetProducts(category, page, pageSize);
return Ok(products);
}
Using HttpContext Directly
[HttpGet]
public IActionResult Search()
{
// Read individual parameter
string query = HttpContext.Request.Query["q"];
// Check if parameter exists
if (HttpContext.Request.Query.ContainsKey("sort"))
{
string sort = HttpContext.Request.Query["sort"];
}
// Get all query string parameters
foreach (var param in HttpContext.Request.Query)
{
Console.WriteLine($"{param.Key} = {param.Value}");
}
return View();
}
Minimal API (ASP.NET Core 6+)
var app = WebApplication.Create(args);
app.MapGet("/search", (string q, int page = 1) =>
{
return Results.Ok(new { Query = q, Page = page });
});
app.Run();
Login Redirect in ASP.NET Core
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(
model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return LocalRedirect(returnUrl);
}
return RedirectToAction("Index", "Home");
}
}
return View(model);
}
Security: Always use
Url.IsLocalUrl()orLocalRedirect()to validate return URLs. Without validation, attackers can craft URLs that redirect users to malicious sites (open redirect attack).
JavaScript (Client-Side)
For completeness, here is how to read query string parameters in JavaScript:
// URL: /page?name=John&age=30
// Modern approach (URLSearchParams)
const params = new URLSearchParams(window.location.search);
const name = params.get('name'); // "John"
const age = params.get('age'); // "30"
// Check if parameter exists
if (params.has('sort')) {
const sort = params.get('sort');
}
Quick Reference
| Framework | Method |
|---|---|
| Web Forms | Request.QueryString["param"] |
| MVC | Action parameter binding or Request.QueryString["param"] |
| ASP.NET Core | [FromQuery] attribute or HttpContext.Request.Query["param"] |
| Minimal API | Method parameter binding |
| JavaScript | new URLSearchParams(window.location.search).get("param") |
Summary
Reading URL query string parameters in ASP.NET is straightforward: use Request.QueryString["name"] in Web Forms, parameter binding in MVC, and [FromQuery] in ASP.NET Core. For the common login redirect pattern, always validate the ReturnUrl with Url.IsLocalUrl() to prevent open redirect attacks.