Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use query strings for small, non-sensitive state that should travel with a URL—for example, a search term, page number, sort order, or selected filter. In ASP.NET Core, model binding can read query parameters and convert them to .NET types; use [FromQuery] when you want to make the source explicit. Validate every value, and keep secrets and sensitive personal information out of URLs.

When query strings are a good fit

A query string is the part of a URL after ?, such as ?term=books&page=2. It is a practical place for compact navigation state when a user should be able to bookmark a view, refresh it, or share it as a link. Microsoft’s ASP.NET Core state-management documentation describes query strings as a way to pass a limited amount of data from one request to another.

  • Good candidates: search phrases, page numbers, sorting choices, and filters that are useful to preserve in a link.
  • Poor candidates: passwords, access tokens, private personal information, large payloads, or state that should not be visible or shareable.

Query parameters are request input, not trusted application state. A user can edit them, so validate their shape, allowed values, and range before using them.

Bind query parameters in ASP.NET Core

ASP.NET Core model binding retrieves request values—including query-string values—and converts strings to .NET types for controller actions or Razor Pages. See Microsoft’s model-binding documentation for binding behavior and validation context.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use an explicit query binding source

For a controller action, [FromQuery] identifies the query string as the source:

public IActionResult Search([FromQuery] string? term, [FromQuery] int page = 1)
{
    if (page < 1)
    {
        return BadRequest("Page must be 1 or greater.");
    }

    // Validate and use term and page.
    return Ok();
}

A request such as /search?term=books&page=2 can bind the values to term and page. With conventional model binding, simple parameters may bind without the attribute; declaring [FromQuery] makes the intended source clear. Microsoft documents binding-source attributes in its ASP.NET Core web API guidance. Check ModelState or apply application-level validation before acting on bound values. Binding and type conversion do not establish that a value is valid for your application.

Keep URL state separate from other application state

Query strings are only one of several state mechanisms. Choose based on whether data must survive requests, be shareable, remain private, or be stored on the server. Microsoft’s state-management overview discusses these mechanisms and their trade-offs.

Mechanism Useful when Important boundary
Query string Compact navigation state should be visible, bookmarkable, or shareable. Public and editable; do not put secrets in it.
Cookie State needs to persist across requests through the browser. Client-held data; consider privacy, security, and cookie configuration.
Session Per-user state needs server-side persistence across requests. Not inherently shareable through a link; protect state-changing flows against CSRF.
TempData Short-lived data must be carried between requests, commonly across a redirect. Intended for temporary rather than durable navigation state.
Hidden field A form needs to submit a value along with its other fields. Client-tamperable; revalidate submitted values.
HttpContext.Items Data is needed only during the current request. Request-local; it does not persist to a later request.
Cache Data needs server-side storage with a defined cache lifetime and access strategy. Choose expiration and scope to suit the application; it is not automatically URL state.

For Blazor, Microsoft recommends representing transient navigation state in the URL. That guidance is about navigation state, not a rule that every component or application value belongs in a query string. See the Blazor state-management overview.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Security and privacy boundaries

Do not put sensitive data in a URL

URLs can be copied, shared, or exposed beyond the intended interaction. Microsoft explicitly warns that query strings are public and should never carry sensitive data in its ASP.NET Core state-management guidance. Do not rely on encoding or hiding a value in the URL as a substitute for keeping it out of the URL.

Validate values and consider the action they trigger

Validate values against expected formats and limits, and make authorization decisions on the server rather than trusting a supplied identifier or role-like value. A query string used to display a read-only filtered page is not, by itself, the same thing as a CSRF vulnerability. For state-changing operations, assess the full request flow and use appropriate CSRF protections. Microsoft’s state-management documentation notes the CSRF implications of preserving state through query strings in relevant flows.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

There is no universal ASP.NET query-string length limit

Do not assume a single maximum applies to every ASP.NET application. Limits depend on the framework, web server, hosting configuration, and deployment path. Microsoft’s HttpRuntimeSection.MaxQueryStringLength reference documents configurable behavior for legacy ASP.NET on .NET Framework using System.Web; it is not a universal ASP.NET Core limit. Check the actual framework and hosting stack for the application. Keep URL state compact regardless of configured limits.

Implementation checklist

  • Put only compact, non-sensitive values in the query string.
  • Use query state when bookmarking, refreshing, or sharing the view is useful.
  • Use [FromQuery] to make binding intent explicit where appropriate.
  • Validate formats, ranges, allowed values, and authorization implications after binding.
  • Use a different mechanism when state must be private, large, request-local, or stored server-side.
  • Verify length behavior against the app’s framework and hosting configuration rather than relying on a legacy setting as a universal limit.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.