Una cadena de consulta (query string) es la parte ?name=value&name=value que va al final de una URL, y en C# tenemos seis formas de construirla. Cuatro de ellas se encargan de aplicar la codificación porcentual (percent-encoding) a los valores. UriBuilder, la que usa la mayoría, no lo hace.
QueryHelpers.AddQueryString() es la respuesta corta para una aplicación ASP.NET Core: le pasas una URL base y un diccionario, y obtienes una URL codificada. HttpUtility.ParseQueryString(string.Empty) es la respuesta para una aplicación de consola sin referencia al framework.
A continuación, construimos una cadena de consulta de las seis formas contra una API real, y pasamos un valor como Simon & Schuster por cada una de ellas para ver cuáles lo resisten.
Empecemos.
¿Qué es la cadena de consulta de una URL?
Una cadena de consulta es la parte de una URL que va después del primer signo de interrogación: una lista de pares name=value unidos por el carácter &. En https://test.com/api/Books?author=rowling&language=english, la cadena de consulta es author=rowling&language=english.
En una cadena de consulta, todo es texto. El servidor lee los nombres y los valores como cadenas y los convierte por su cuenta; en la transmisión no viajan valores con tipo.
Cuatro caracteres aportan estructura en lugar de datos. ? abre la consulta, & separa un par del siguiente, = separa un nombre de su valor y # termina la cadena de consulta y abre el fragmento, que el navegador conserva y nunca envía.
Por eso construir una cadena de consulta no es concatenar cadenas. Si alguno de esos cuatro caracteres aparece dentro de un nombre o de un valor, habría que aplicarle antes la codificación porcentual; si no, el receptor puede leer una consulta distinta de la que enviamos.
El valor Simon & Schuster, escrito tal cual en una URL, llega como dos parámetros: author con el valor Simon , y un segundo llamado Schuster.
Veamos un ejemplo de cadena de consulta:
https://test.com/api/Books?author=rowling&language=english
Aquí, por ejemplo, la URL empieza con la dirección base https://test.com/api/Books. Después del signo de interrogación (?), la cadena de consulta comienza con el primer par clave-valor: author=rowling. En este caso, “author” es la clave y “rowling” es el valor. El ampersand (&) separa el primer par clave-valor del segundo: language=english.
¿Qué API de C# construyen cadenas de consulta?
Hay varias formas de construir la cadena de consulta de una URL:
- Concatenación de cadenas
- UriBuilder
- ParseQueryString
- QueryHelpers
- QueryBuilder
- QueryString.Create
Veamos cada uno de estos enfoques para construir una cadena de consulta.
Configuración de la aplicación
Para simular una llamada real a una API con la cadena de consulta, podemos configurar una API GET sencilla que acepte una cadena de consulta para hacer pruebas. Esta API representa un servicio de libros que acepta author y language como parámetros de consulta y devuelve algunos datos de libros.
Podemos construir una cadena de consulta y luego hacer una llamada a la API con ella para comprobar si funciona. Sin embargo, configurar la API es opcional y no es obligatorio en este artículo. Consulta el código para obtener más información sobre la API.
Para empezar, vamos a crear una aplicación de consola y a definir una clase BooksApiService:
public class BooksApiService
{
private const string BaseApiUrl = "https://localhost:7220/api/Books";
}
Aquí, declaramos una constante BaseApiUrl, que contiene la URL base de un endpoint de la API. Es privada, así que todos los fragmentos de código de más abajo que la usan van dentro de esta clase.
Ahora, veamos cada apartado en detalle.
Usar la concatenación de cadenas
La concatenación de cadenas es una de las técnicas tradicionales para construir cadenas de consulta en C#. Esta técnica combina varias cadenas, incluidos los nombres y los valores de los parámetros, para crear una cadena de consulta completa. Aunque ofrece control, puede resultar engorrosa con consultas complejas o con muchos parámetros.
Primero, crearemos una clase de utilidades QueryStringHelper. Esta clase contendrá varios métodos, y cada uno usará una técnica distinta para construir cadenas de consulta.
Ahora, vamos a crear el primer método para construir una cadena de consulta mediante concatenación de cadenas:
public static class QueryStringHelper
{
public static string BuildUrlWithQueryStringUsingStringConcat(
string basePath, Dictionary<string, string> queryParams)
{
var queryString = string.Join("&", queryParams.Select(kvp => $"{kvp.Key}={kvp.Value}"));
return $"{basePath}?{queryString}";
}
}
Primero, dentro de la clase QueryStringHelper, definimos un método que acepta basePath y queryParams como parámetros de entrada. Después, usamos el método LINQ Select() para transformar el diccionario en una colección de pares clave-valor con formato. A continuación, usamos el método string.Join() para concatenar esos pares con “&” como separador.
Seguidamente, concatenamos basePath y queryString para formar la URL completa y la devolvemos.
En este ejemplo, uno de los principales retos es la codificación de URL y URI de los parámetros de consulta. Si un nombre de autor tiene caracteres especiales y no los codificamos al pasarlo como parámetro de consulta, podemos acabar con una URL mal formada.
Veamos un ejemplo de cómo codificar los parámetros de consulta:
public static string BuildUrlWithQueryStringUsingStringConcat(
string basePath, Dictionary<string, string> queryParams)
{
var queryString = string.Join("&",
queryParams.Select(kvp => $"{HttpUtility.UrlEncode(kvp.Key)}={HttpUtility.UrlEncode(kvp.Value)}"));
return $"{basePath}?{queryString}";
}
Aquí, usamos el método HttpUtility.UrlEncode() para codificar tanto Key como Value de queryParams.
Por último, invoquemos el método BuildUrlWithQueryStringUsingStringConcat():
var query = new Dictionary<string, string>
{
{ "author", "George Orwell" },
{ "language", "english" }
};
Console.WriteLine(QueryStringHelper.BuildUrlWithQueryStringUsingStringConcat(BaseApiUrl, query));
//prints https://localhost:7220/api/Books?author=George+Orwell&language=english
Empezamos inicializando un objeto Dictionary, que contiene los pares clave-valor que representan los parámetros de consulta de la solicitud a la API. Pasamos “George Orwell” como autor y “english” como idioma.
Por último, llamamos al método BuildUrlWithQueryStringUsingStringConcat() y le pasamos la constante BaseApiUrl y la variable query para construir la URL completa.
La concatenación de cadenas no es la única forma manual de montar una cadena de consulta. Vale la pena conocer otras dos: la interpolación de cadenas y StringBuilder.Append().
Usar la clase UriBuilder
La clase UriBuilder de C# ofrece una forma potente y cómoda de construir instancias de System.Uri y copias modificadas de las ya existentes. Con ella podemos crear o manipular URL con distintos componentes, como el esquema, el host, el puerto, la ruta y la cadena de consulta.
Port vale -1 cuando no se establece ningún puerto, y eso es lo que elimina un puerto explícito del resultado; si analizamos una URL que no lo incluye, obtenemos en cambio el puerto predeterminado del esquema.
La clase UriBuilder escapa los caracteres que no son válidos en un URI, como el espacio de Jane Austen, pero no escapa los delimitadores de consulta &, = y # dentro de un valor; lo vemos en el siguiente apartado.
La referencia de UriBuilder.Query de Microsoft indica qué estándar sigue: “La información de la consulta se escapa según la RFC 2396”. Ese estándar reserva & y = para usarlos dentro de una consulta, así que escapar según él los deja exactamente donde están. El carácter # es un caso más grave: la RFC 2396 lo convierte en el delimitador que cierra la consulta y abre el fragmento, así que también sobrevive sin escapar, y todo lo que va detrás deja de formar parte de la consulta.

Ebook gratis
¿Tu Web API está lista para producción?
33 puntos que comprobar antes de desplegarla, con la solución de cada uno. Un PDF gratuito de 76 páginas para .NET 10.
El ebook está en inglés.
Descarga la checklist gratisPDF gratuito. Un solo correo para enviártelo. Puedes darte de baja cuando quieras.
Vamos a crear otro método en la clase QueryStringHelper para mostrar cómo se usa la clase UriBuilder:
public static string BuildUrlWithQueryStringUsingUriBuilder(string basePath, Dictionary<string, string> queryParams)
{
var uriBuilder = new UriBuilder(basePath)
{
Query = string.Join("&", queryParams.Select(kvp => $"{kvp.Key}={kvp.Value}"))
};
return uriBuilder.Uri.AbsoluteUri;
}
Empezamos creando una instancia de la clase UriBuilder y la inicializamos con la URL base de la API. Después, concatenamos los pares clave-valor con el método string.Join() y establecemos la propiedad Query de la instancia de uriBuilder. Por último, obtenemos la URL completa de la API accediendo a la propiedad Uri de la instancia de UriBuilder y leyendo después su propiedad AbsoluteUri.
Ahora, invoquemos el método BuildUrlWithQueryStringUsingUriBuilder():
var query = new Dictionary<string, string>
{
{ "author", "Jane Austen" },
{ "language", "english" }
};
Console.WriteLine(QueryStringHelper.BuildUrlWithQueryStringUsingUriBuilder(BaseApiUrl, query));
//prints https://localhost:7220/api/Books?author=Jane%20Austen&language=english
De forma similar, inicializamos un objeto Dictionary que contiene los parámetros de consulta. Después, pasamos la constante BaseApiUrl y la variable query al método BuildUrlWithQueryStringUsingUriBuilder() para obtener una URL completa. La clase UriBuilder codifica el valor del parámetro author, que contiene un espacio.
¿UriBuilder codifica los valores de los parámetros de consulta?
No. UriBuilder solo escapa los caracteres que no son válidos en ninguna parte de un URI. Los delimitadores de consulta sí son válidos en un URI, así que pasan tal cual.
Si asignamos author=Simon & Schuster a la propiedad Query y volvemos a leer Uri.AbsoluteUri, obtenemos ?author=Simon%20&%20Schuster. El espacio se ha convertido en %20. El carácter & sigue siendo un &, así que el receptor lee un parámetro llamado author con el valor Simon , y un segundo llamado Schuster.
El carácter # es peor, y es el que más probabilidades tiene de aparecer en un artículo sobre C#. tag=C#&language=english se corta en el signo #: todo lo que va detrás pasa a ser el fragmento, el servidor recibe tag=C y language no llega nunca.
Así que UriBuilder es un ensamblador de URL, no un codificador de consultas. Es la clase adecuada para el esquema, el host, el puerto y la ruta, y espera que la cadena que asignamos a Query ya esté codificada.
La solución es una sola línea. Construimos la consulta con algo que codifique y luego pasamos la cadena terminada a UriBuilder.
El diagrama sigue un mismo valor a través de ambas API y se detiene donde el servidor lo analiza, porque es ahí donde aparece la diferencia.

Así que construimos la consulta con QueryString.Create() (necesita la referencia al framework Microsoft.AspNetCore.App que añadimos más abajo) y dejamos que UriBuilder monte el resto de la URL a su alrededor:
public static string BuildUrlWithQueryStringUsingUriBuilderSafely(
string basePath, Dictionary<string, string?> queryParams)
{
var uriBuilder = new UriBuilder(basePath)
{
Query = QueryString.Create(queryParams).Value
};
return uriBuilder.Uri.AbsoluteUri;
}
La propiedad Value nos da la consulta codificada con su signo de interrogación inicial, que es exactamente la forma que espera la propiedad Query. Con author establecido en Simon & Schuster y tag establecido en C#, al analizar el resultado se obtienen de nuevo los valores que pusimos:
https://localhost:7220/api/Books?author=Simon%20%26%20Schuster&tag=C%23
Usar HttpUtility.ParseQueryString
El método HttpUtility.ParseQueryString() forma parte del espacio de nombres System.Web de C#. Este método resulta útil cuando creamos o manipulamos cadenas de consulta en aplicaciones web.
Nos permite analizar una cadena de consulta existente para obtener una colección de pares clave-valor, modificar esos pares y generar una nueva cadena de consulta.
Descomponer una cadena de consulta a mano implica dividir una cadena por & y =, y vale la pena conocer las sobrecargas que lo hacen para cuando no tengamos un método auxiliar disponible.
Vamos a crear un nuevo método dentro de la clase QueryStringHelper para mostrar esta técnica:
public static string BuildUrlWithQueryStringUsingParseQueryStringMethod(
string basePath, Dictionary<string, string> queryParams)
{
var query = HttpUtility.ParseQueryString(string.Empty);
foreach (var dict in queryParams)
{
query[dict.Key] = dict.Value;
}
return string.Join("?", basePath, query.ToString());
}
Aquí, creamos un NameValueCollection vacío con el método HttpUtility.ParseQueryString(string.Empty).
Internamente, este método crea una instancia de HttpQSCollection, una clase derivada de NameValueCollection que no es accesible públicamente. Como es una clase privada, tenemos que usar esta forma poco habitual de inicialización. La ventaja de esta colección especial es que maneja automáticamente los valores null y codifica correctamente para URL todos los pares clave-valor.
Asignar null mediante el indexador escribe un valor vacío (author=) en lugar de omitir el parámetro, y no se lanza ninguna excepción. Si lo añadimos con Add(name, null), en cambio, sí se descarta. QueryHelpers.AddQueryString() descarta un valor null del diccionario.
Ahora, llamemos al método:
var query = new Dictionary<string, string>
{
{ "author", "Agatha Christie" },
{ "language", "english" }
};
Console.WriteLine(QueryStringHelper.BuildUrlWithQueryStringUsingParseQueryStringMethod(BaseApiUrl, query));
//prints https://localhost:7220/api/Books?author=Agatha+Christie&language=english
Aquí, creamos los parámetros de consulta con el objeto Dictionary e invocamos el método BuildUrlWithQueryStringUsingParseQueryStringMethod() para obtener la URL completa.
Usar QueryHelpers.AddQueryString
QueryHelpers es una clase de utilidades que proporciona el espacio de nombres Microsoft.AspNetCore.WebUtilities. Incluye el método AddQueryString(), que construye la cadena de consulta añadiendo o anexando parámetros a una URL existente.
El método QueryHelpers.AddQueryString() garantiza que los nombres y los valores de los parámetros se codifiquen correctamente para formar una URL válida.
Como anexa, también es el método que usamos cuando la URL ya lleva una consulta, y hay un artículo completo sobre cómo añadir o actualizar parámetros en una URL que ya tiene una consulta.
Como primer paso, incluyamos Microsoft.AspNetCore.App como FrameworkReference en el archivo .csproj, dentro de un ItemGroup:
<FrameworkReference Include="Microsoft.AspNetCore.App" />
Añadir esta referencia garantiza que podamos usar el método QueryHelpers.AddQueryString() del espacio de nombres Microsoft.AspNetCore.WebUtilities. La misma referencia también nos da acceso a QueryBuilder y QueryString. HttpUtility no necesita nada: System.Web.HttpUtility forma parte del framework compartido base.
Ahora, vamos a crear un nuevo método para mostrar cómo se usa el método QueryHelpers.AddQueryString():
public static string BuildUrlWithQueryStringUsingAddQueryStringMethod(
string basePath, Dictionary<string, string?> queryParams)
{
return QueryHelpers.AddQueryString(basePath, queryParams);
}
Aquí, usamos el método QueryHelpers.AddQueryString() para generar la cadena de consulta. Le pasamos basePath y el diccionario queryParams como entrada, y obtenemos la URL completa.
En este método, aceptamos expresamente Dictionary<string, string?> con valores de cadena anulables porque el método QueryHelpers.AddQueryString() admite valores anulables, lo que da flexibilidad para manejar parámetros de consulta opcionales.
Después, invoquemos el método:
var query = new Dictionary<string, string?>
{
{ "author", "Haruki Murakami" },
{ "language", "japanese" }
};
Console.WriteLine(QueryStringHelper.BuildUrlWithQueryStringUsingAddQueryStringMethod(BaseApiUrl, query));
//prints https://localhost:7220/api/Books?author=Haruki%20Murakami&language=japanese
De forma similar, creamos un objeto Dictionary que contiene los parámetros de consulta y pasamos la variable query y la constante BaseApiUrl al método BuildUrlWithQueryStringUsingAddQueryStringMethod() para construir la URL completa. Lo declaramos como Dictionary<string, string?> para que coincida con el parámetro del método; un Dictionary<string, string> normal compila, pero genera la advertencia CS8620.
Usar la clase QueryBuilder
La clase QueryBuilder forma parte del espacio de nombres Microsoft.AspNetCore.Http.Extensions y sirve para construir una cadena de consulta. En esencia, la clase QueryBuilder nos permite construir una cadena de consulta añadiendo pares clave-valor. Implementa la interfaz IEnumerable<KeyValuePair<String,String>>, lo que significa que podemos iterar sobre los pares clave-valor que contiene.
Veamos un ejemplo:
public static string BuildUrlWithQueryStringUsingQueryBuilderClass(
string basePath, Dictionary<string, string> queryParams)
{
var queryBuilder = new QueryBuilder(queryParams);
return basePath + queryBuilder;
}
Aquí, creamos una instancia de la clase QueryBuilder y pasamos queryParams al constructor, que inicializa la instancia de la clase QueryBuilder.
Cuando concatenamos un objeto queryBuilder con una cadena, se llama implícitamente al método ToString() de la clase QueryBuilder. En el caso de la clase QueryBuilder, esta sobrescribe (override) el método ToString() para devolver la representación como cadena de consulta de los pares clave-valor almacenados en el objeto queryBuilder.

Ebook gratis
¿Tu Web API está lista para producción?
33 puntos que comprobar antes de desplegarla, con la solución de cada uno. Un PDF gratuito de 76 páginas para .NET 10.
El ebook está en inglés.
Descarga la checklist gratisPDF gratuito. Un solo correo para enviártelo. Puedes darte de baja cuando quieras.
Por eso podemos concatenar el objeto queryBuilder con basePath para crear una URL completa.
Sigamos e invoquemos el método:
var query = new Dictionary<string, string>
{
{ "author", "Gabriel Garcia" },
{ "language", "spanish" }
};
Console.WriteLine(QueryStringHelper.BuildUrlWithQueryStringUsingQueryBuilderClass(BaseApiUrl, query));
//prints https://localhost:7220/api/Books?author=Gabriel%20Garcia&language=spanish
Aquí, inicializamos un objeto Dictionary y lo pasamos al método BuildUrlWithQueryStringUsingQueryBuilderClass() para construir la URL completa.
Usar QueryString.Create
El método QueryString.Create() es una forma cómoda de crear un objeto de cadena de consulta a partir de pares clave-valor.
El método QueryString.Create() ofrece tres sobrecargas. La primera, Create(string name, string value), nos permite crear una cadena de consulta con un solo par clave-valor.
La segunda sobrecarga, Create(IEnumerable<KeyValuePair<string, string?>> parameters), acepta una colección de pares clave-valor cuyos valores son cadenas anulables.
Por último, la tercera sobrecarga, Create(IEnumerable<KeyValuePair<string, StringValues>> parameters), recibe una colección de pares clave-valor cuyos valores son de tipo StringValues.
Vamos a crear un nuevo método en la clase QueryStringHelper:
public static string BuildUrlWithQueryStringUsingCreateMethod(
string basePath, Dictionary<string, string?> queryParams)
{
var queryString = QueryString.Create(queryParams);
return basePath + queryString;
}
Aquí, definimos un método que acepta un Dictionary<string, string?>, lo que permite valores de cadena anulables. Lo hacemos así porque la segunda sobrecarga del método QueryString.Create() admite valores anulables.
Aunque este método no acepta explícitamente un Dictionary, podemos pasarle un Dictionary. Es posible porque Dictionary implementa la interfaz IEnumerable<KeyValuePair<string, string?>>. Después, usamos el método QueryString.Create() y le pasamos el objeto de diccionario queryParams para construir una cadena de consulta.
Cuando los parámetros proceden de una clase y no de un diccionario, construir la cadena de consulta a partir de un objeto en lugar de un diccionario nos ahorra montar antes el diccionario a mano.
Por último, llamemos al método:
var query = new Dictionary<string, string?>
{
{ "author", "Leo Tolstoy" },
{ "language", "russian" }
};
Console.WriteLine(QueryStringHelper.BuildUrlWithQueryStringUsingCreateMethod(BaseApiUrl, query));
//prints https://localhost:7220/api/Books?author=Leo%20Tolstoy&language=russian
Aquí, creamos un objeto Dictionary que representa los parámetros de consulta e invocamos el método BuildUrlWithQueryStringUsingCreateMethod() para formar la URL completa.
¿Cómo añadir parámetros de consulta a una solicitud de HttpClient?
HttpClient no tiene ninguna API para parámetros de consulta. GetAsync() recibe una URL o un Uri, así que la cadena de consulta tiene que estar terminada antes de hacer la llamada.
En una aplicación ASP.NET Core, lo habitual es aplicar QueryHelpers.AddQueryString() a una ruta relativa y pasar el resultado a un cliente cuya BaseAddress ya está configurada. La dirección base contiene el host, la llamada contiene los parámetros, y ninguna de las dos sabe nada de la otra.
AddQueryString() anexa en lugar de reemplazar. Si se llama sobre una ruta que ya lleva una consulta, la amplía, así que /api/Books?page=2 con author añadido se convierte en /api/Books?page=2&author=Orwell.
Ese comportamiento de anexar es lo que hay que vigilar cuando una ruta y un filtro aportan cada uno sus parámetros. Construye primero el diccionario completo y haz una sola llamada, en lugar de encadenar llamadas. Y BaseAddress necesita su barra final, o la combinación de Uri descarta el último segmento de la ruta.
El envío de la solicitud no codifica los delimitadores. HttpClient envía la URL que le damos, así que la codificación ya se ha hecho o no se hará en absoluto.
Nuestro ejemplo ya hace esa llamada. BooksApiService construye la URL y se la pasa directamente al cliente:
public async Task<string> GetWithQueryParamsUsingAddQueryStringMethod(string author, string language)
{
var query = new Dictionary<string, string?>
{
{ "author", author },
{ "language", language }
};
return await HttpGetAsync(QueryStringHelper.BuildUrlWithQueryStringUsingAddQueryStringMethod(BaseApiUrl, query));
}
public async Task<string> HttpGetAsync(string apiUrl)
{
var response = await _httpClientWrapper.GetAsync(apiUrl);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
La URL terminada es lo único que pasa a HttpClient. Al otro lado de la llamada, leer esos valores en el servidor es la imagen especular de este trabajo.
En una aplicación real tampoco crearíamos el cliente nosotros mismos con new; configurar el HttpClient por el que pasa esta llamada es tarea de IHttpClientFactory.
¿Qué método para cadenas de consulta es el más seguro?
Dos de las seis formas son inseguras por defecto. QueryHelpers.AddQueryString(), QueryString.Create(), QueryBuilder y la colección ParseQueryString aplican codificación porcentual a nombres y valores. La concatenación de cadenas codifica si nos acordamos de llamar nosotros mismos a HttpUtility.UrlEncode(). UriBuilder no codifica nunca ningún delimitador.
QueryHelpers.AddQueryString() es la opción por defecto dentro de una aplicación ASP.NET Core: recibe una URL base y un diccionario, devuelve una URL codificada y anexa los parámetros a cualquier consulta que la URL ya tuviera.
HttpUtility.ParseQueryString(string.Empty) es la opción para una aplicación de consola simple, porque System.Web.HttpUtility está en el framework compartido base y no necesita ninguna referencia al framework.
Las dos no coinciden en el tratamiento de null. AddQueryString() descarta una entrada del diccionario cuyo valor es null; el indexador de ParseQueryString la conserva y escribe name=. Ninguna de las dos lanza una excepción.
Tampoco coinciden en el tratamiento de los espacios. HttpUtility.UrlEncode() escribe +, los métodos auxiliares de ASP.NET Core escriben %20, y ambos se decodifican como un espacio.
QueryBuilder es ese mismo codificador otra vez, usado de llamada en llamada a Add(), lo que encaja con una consulta que se monta a lo largo de varios métodos en lugar de construirse a partir de un solo diccionario.
| Enfoque | ¿Codifica & = # en los valores? | Un valor null se convierte en | Nombre repetido | Úsalo cuando |
|---|---|---|---|---|
Concatenación de cadenas + HttpUtility.UrlEncode() | Solo si llamamos nosotros a UrlEncode() | lo que escribamos | lo construimos nosotros | necesitas control total y aceptas toda la responsabilidad |
UriBuilder (asignando Query) | No | no aplica | lo construimos nosotros | se trata de montar el esquema, el host, el puerto y la ruta, no la consulta |
HttpUtility.ParseQueryString(string.Empty) | Sí | name= | Add() dos veces con el mismo nombre | una aplicación de consola sin FrameworkReference |
QueryHelpers.AddQueryString() | Sí | el parámetro se descarta | sobrecarga con StringValues | ASP.NET Core, y cuando la URL puede tener ya una consulta |
QueryBuilder | Sí | no aplica (recibe string) | Add(name, IEnumerable<string>) | se añaden los parámetros de uno en uno |
QueryString.Create() | Sí | name= | sobrecarga con StringValues | una sola llamada a partir de un diccionario, sin URL base de por medio |
Una vez montada la URL, comprobar que la URL que hemos construido es válida requiere una sola llamada, y vale la pena hacerla cuando alguna parte de la URL procede de la entrada del usuario.
Conclusión
En este artículo, hemos visto varios enfoques para construir una cadena de consulta en C#. El método que elijamos dependerá de nuestras necesidades y preferencias concretas.
En resumen, podemos usar la concatenación de cadenas y otras técnicas manuales si necesitamos una forma sencilla de construir una cadena de consulta. Sin embargo, con la concatenación de cadenas debemos asegurarnos de codificar correctamente los nombres y los valores de los parámetros.
Por otro lado, si necesitamos construir consultas complejas o trabajar con muchos parámetros, podemos usar un método más robusto, como el método HttpUtility.ParseQueryString(), el método QueryHelpers.AddQueryString(), la clase QueryBuilder o el método QueryString.Create().
No necesitamos codificar a mano los parámetros de la cadena de consulta cuando usamos cualquiera de esos cuatro métodos, porque se encargan internamente de la codificación de URL. UriBuilder es la excepción, y es el que hay que combinar con un codificador en lugar de pasarle una consulta sin codificar.
Probado con .NET 10.