ASP.NET
MVC
QueryString
Web Development
C#

ASP.NET MVC - Getting QueryString values

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Query string values are a common way to pass lightweight request data in ASP.NET MVC applications. You will use them for filtering, paging, sorting, and campaign tracking on read only routes. The key is to bind them safely, validate them early, and keep action methods simple.

Automatic Model Binding in Action Parameters

The cleanest option is to declare expected query values as action parameters. MVC model binding will map query keys to parameters by name and convert types when possible.

csharp
1using System;
2using System.Web.Mvc;
3
4public class ProductsController : Controller
5{
6    // Example URL:
7    // /Products/List?category=books&page=2&pageSize=20
8    public ActionResult List(string category, int page = 1, int pageSize = 20)
9    {
10        if (page < 1) page = 1;
11        if (pageSize < 1 || pageSize > 100) pageSize = 20;
12
13        ViewBag.Category = category ?? "all";
14        ViewBag.Page = page;
15        ViewBag.PageSize = pageSize;
16
17        return View();
18    }
19}

This keeps your code readable and testable. Optional parameters with defaults are especially useful for paging and sorting scenarios.

For dates and decimals, parsing depends on culture settings. If your application serves multiple locales, prefer explicit formats and predictable parsing rules to avoid subtle bugs.

Accessing Query Values Directly

You can also read query values from Request.QueryString. This is useful when keys are dynamic, unknown at compile time, or processed in generic middleware style logic.

csharp
1using System;
2using System.Web.Mvc;
3
4public class SearchController : Controller
5{
6    public ActionResult Index()
7    {
8        var q = Request.QueryString["q"];
9        var sort = Request.QueryString["sort"];
10        var rawPage = Request.QueryString["page"];
11
12        int page;
13        if (!int.TryParse(rawPage, out page) || page < 1)
14        {
15            page = 1;
16        }
17
18        ViewBag.Query = q ?? string.Empty;
19        ViewBag.Sort = sort ?? "relevance";
20        ViewBag.Page = page;
21
22        return View();
23    }
24}

Direct access is flexible, but manual parsing can become repetitive. When parameters are known, action parameter binding is usually the better default.

Binding to a View Model

As query options grow, use a strongly typed model. This gives one validation point and cleaner signatures.

csharp
1using System.ComponentModel.DataAnnotations;
2using System.Web.Mvc;
3
4public class ProductFilter
5{
6    public string Category { get; set; }
7
8    [Range(1, 1000)]
9    public int Page { get; set; } = 1;
10
11    [Range(1, 100)]
12    public int PageSize { get; set; } = 20;
13
14    public string Sort { get; set; } = "name";
15}
16
17public class CatalogController : Controller
18{
19    public ActionResult Browse(ProductFilter filter)
20    {
21        if (!ModelState.IsValid)
22        {
23            filter.Page = 1;
24            filter.PageSize = 20;
25        }
26
27        return View(filter);
28    }
29}

This pattern scales well for advanced search pages and helps prevent accidental logic drift between controllers.

Security and Validation Considerations

Query strings are user controlled input. Never trust them for authorization decisions. Validate ranges, normalize text fields, and apply allow lists for sort column names.

Also avoid putting secrets in query strings. URLs are logged by browsers, proxies, and servers, so sensitive values should go in headers or protected request bodies.

When building paging links in views, preserve only the query keys your page actually supports. Carrying every incoming key forward can accidentally keep obsolete filters alive across navigation, which makes troubleshooting difficult. Generate URLs from a known model instead of concatenating raw query strings.

For SEO sensitive pages, canonical URLs matter. If the same content can be reached through many equivalent query combinations, consider redirecting to one normalized route so caching and indexing behavior stays consistent.

Common Pitfalls

A frequent problem is assuming a query value is always present. Missing keys return null, so null checks and defaults are required.

Another issue is using int.Parse directly. One malformed request can throw and break the request pipeline. Use TryParse or model validation attributes.

Many teams also forget to cap paging values. A very large page size can create heavy database queries and performance incidents. Apply strict upper bounds.

Finally, parameter naming mismatches can silently fail binding. Keep query key names aligned with action parameter names or use explicit binding attributes when needed.

Summary

  • Prefer action parameter binding for known query keys.
  • Use Request.QueryString for dynamic or ad hoc key handling.
  • Move complex filters into a strongly typed model with validation.
  • Treat query values as untrusted input and validate every field.
  • Keep defaults and limits explicit to protect performance and reliability.

Course illustration
Course illustration

All Rights Reserved.