Passing an ampersand (&) in a QueryString value in ASP.NET
The ampersand separates parameters in a query string. Put Tom & Jerry into a URL as it is and the server sees a parameter title=Tom plus a stray parameter named Jerry. The value must be URL-encoded, so the & travels as %26.
The problem
string title = "Tom & Jerry";
Response.Redirect("Search.aspx?title=" + title); // wrong
// URL: Search.aspx?title=Tom & Jerry
// Request.QueryString["title"] on the next page: "Tom " (and a key " Jerry")
Other characters cause similar trouble: # starts the fragment and is never sent to the server, + is decoded as a space, = and % confuse parsing.
Encoding in C#
string url = "Search.aspx?title=" + HttpUtility.UrlEncode(title);
// Search.aspx?title=Tom+%26+Jerry
string url2 = "Search.aspx?title=" + Uri.EscapeDataString(title);
// Search.aspx?title=Tom%20%26%20Jerry
Both are correct. HttpUtility.UrlEncode uses + for spaces (form encoding); Uri.EscapeDataString uses %20. ASP.NET decodes both forms. Encode each value separately, never the whole URL, or the ?, = and & that structure it would be encoded too.
For several parameters, HttpUtility.ParseQueryString(string.Empty) builds and encodes the whole query, as shown in Passing multiple QueryString parameters.
Reading it
string title = Request.QueryString["title"]; // "Tom & Jerry", already decoded
Do not call UrlDecode again: decoding twice turns a literal %26 typed by the user into an ampersand and a literal + into a space.
In markup
<asp:HyperLink runat="server"
NavigateUrl='<%# "Search.aspx?title=" + HttpUtility.UrlEncode((string)Eval("Title")) %>'
Text='<%#: Eval("Title") %>' />
Two different encodings meet here. The URL value is URL-encoded (%26). The link as a whole is then written into an HTML attribute, where the separator between parameters should be written &; the HyperLink control handles that HTML encoding for you. When writing an <a href> by hand with two parameters, write ?a=1&b=2 in the HTML source; browsers tolerate a bare & in most cases, but the escaped form is always valid.
In JavaScript
var url = "Search.aspx?title=" + encodeURIComponent("Tom & Jerry"); // Tom%20%26%20Jerry
// or let the browser do it:
var p = new URLSearchParams({ title: "Tom & Jerry", page: 2 });
location.href = "Search.aspx?" + p; // title=Tom+%26+Jerry&page=2
Use encodeURIComponent, not encodeURI: the latter leaves &, = and ? unencoded because it is meant for whole URLs. Reading values on the client is covered in Read a QueryString value in the browser.
Common mistakes
- Encoding the whole URL including
?and&: the server receives one parameter with a strange name. - Encoding twice (in code, then again by a control): the value arrives with
%26instead of&. - Using
Server.HtmlEncodefor a URL value:&is the HTML form and still breaks the query string.
Official documentation
- Microsoft Learn: HttpUtility.UrlEncode, Uri.EscapeDataString
- MDN: encodeURIComponent()
- IETF: RFC 3986, percent-encoding