← All articles.NET & JavaScript

Working with query strings in ASP.NET Core

Read query values and build URLs with the framework’s helpers, without assembling the escaping by hand.

Query strings look simple until a value contains an ampersand, a space or another URL. Building them by joining strings is an easy way to turn an ordinary value into an accidental parameter.

The original version of this article introduced a small helper library for classic ASP.NET. For a modern ASP.NET Core application, start with the framework’s request collection and QueryHelpers.

Read a parameter from the current request

In a controller action, the query collection is available through Request.Query:

var term = Request.Query["q"].ToString();

You can also let model binding supply an action parameter:

[HttpGet]
public IActionResult Search([FromQuery] string? q)
{
    return Ok(new { query = q });
}

A parameter can appear more than once. If repeated values are meaningful, work with the collection rather than assuming that every key has exactly one value. Validate user input before using it in the rest of your application.

Add parameters to a URL

QueryHelpers.AddQueryString handles encoding for you:

using Microsoft.AspNetCore.WebUtilities;

var url = QueryHelpers.AddQueryString(
    "/search/",
    new Dictionary<string, string?>
    {
        ["q"] = "synths & samples",
        ["page"] = "2"
    });

// /search/?q=synths%20%26%20samples&page=2

Pass the unescaped value. Encoding it yourself first can lead to double encoding.

The helper also handles a URL that already has a query string. Adding a key does not mean replacing every existing occurrence of that key, so decide deliberately whether repeated parameters are acceptable.

Parse a separate query string

When the query isn’t part of the current request, ParseQuery turns it into a collection:

using Microsoft.AspNetCore.WebUtilities;

var parameters = QueryHelpers.ParseQuery("?q=ambient&page=2");
var query = parameters["q"].ToString();

If you need to replace or remove values, make those changes to a parsed collection and build the result from the intended set of keys. Avoid global string replacements: the same text can legitimately occur inside an encoded value.

Use the helper that fits the job

In Razor views, tag helpers are often the clearest way to generate links with route and query values. In C# code, QueryHelpers is a useful building block. Neither makes an untrusted redirect destination safe: validating a destination is a separate responsibility.

See Microsoft’s reference for AddQueryString and ParseQuery for the available overloads.