Uma query string é o trecho ?name=value&name=value no fim de uma URL, e em C# temos seis formas de montá-la. Quatro delas fazem a codificação percentual (percent-encoding) dos valores por nós. UriBuilder, a que a maioria das pessoas escolhe, não faz.

QueryHelpers.AddQueryString() é a resposta curta para uma aplicação ASP.NET Core: passe uma URL base e um dicionário e receba de volta uma URL codificada. HttpUtility.ParseQueryString(string.Empty) é a resposta para uma aplicação de console sem referência de framework.

A seguir, montamos uma query string das seis formas usando uma API real e passamos um valor como Simon & Schuster por cada uma delas para ver quais sobrevivem a ele.

Para baixar o código-fonte deste artigo, você pode acessar nosso repositório no GitHub.

Vamos começar.

O que é a query string de uma URL?

A query string é a parte da URL que vem depois do primeiro ponto de interrogação: uma lista de pares name=value unidos pelo e comercial. Em https://test.com/api/Books?author=rowling&language=english, a query string é author=rowling&language=english.

Tudo em uma query string é texto. Um servidor lê nomes e valores como strings e faz a conversão por conta própria; nada trafega pela rede como valor tipado.

Quatro caracteres servem de estrutura, e não de dados. ? abre a query string, & separa um par do seguinte, = separa o nome do valor e # encerra a query string e inicia o fragmento, que o navegador guarda e nunca envia.

É por isso que montar uma query string não é uma simples concatenação de strings. Qualquer um desses quatro caracteres dentro de um nome ou de um valor deve ser codificado antes, senão o destinatário pode ler uma query string diferente da que enviamos.

O valor Simon & Schuster, escrito diretamente em uma URL, chega como dois parâmetros: author com o valor Simon e um segundo chamado Schuster.

Vejamos um exemplo de query string:

https://test.com/api/Books?author=rowling&language=english

Aqui, por exemplo, a URL começa com o endereço base https://test.com/api/Books. Depois do ponto de interrogação (?), a query string começa com o primeiro par chave-valor: author=rowling. Nele, “author” é a chave e “rowling” é o valor. O e comercial (&) separa o primeiro par chave-valor do segundo: language=english.

Quais APIs do C# montam query strings?

Há várias formas de montar a query string de uma URL:

  • Concatenação de strings
  • UriBuilder
  • ParseQueryString
  • QueryHelpers
  • QueryBuilder
  • QueryString.Create

Vamos ver cada abordagem para montar uma query string.

Configuração da aplicação

Para simular uma chamada real a uma API usando a query string, podemos configurar uma API GET simples que aceita uma query string para fins de teste. Essa API representa um serviço de livros que aceita author e language como parâmetros de query string e retorna alguns detalhes dos livros.

Podemos montar uma query string e depois fazer uma chamada à API com ela para testar se funciona. No entanto, configurar a API é opcional neste artigo, não obrigatório. Consulte o código para mais informações sobre a API.

Para começar, vamos criar uma aplicação de console e definir uma classe BooksApiService:

public class BooksApiService
{
    private const string BaseApiUrl = "https://localhost:7220/api/Books";
}

Aqui, declaramos uma constante BaseApiUrl, que contém a URL base de um endpoint da API. Ela é privada, então todo trecho de código a seguir que a utiliza fica dentro desta classe.

Agora, vamos ver cada seção em detalhes.

Uso da concatenação de strings

A concatenação de strings é uma das técnicas tradicionais para montar query strings em C#. Essa técnica combina várias strings, incluindo nomes e valores de parâmetros, para criar uma query string completa. Embora ofereça controle, ela pode ser trabalhosa quando lidamos com query strings complexas ou com muitos parâmetros.

Primeiro, vamos criar uma classe utilitária QueryStringHelper. Essa classe vai conter vários métodos, cada um usando uma técnica diferente para montar query strings.

Agora, vamos criar o primeiro método para montar uma query string usando concatenação de strings:

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}";
    }
}

Primeiro, dentro da classe QueryStringHelper, definimos um método que aceita basePath e queryParams como parâmetros de entrada. Em seguida, usamos o método LINQ Select() para transformar o dicionário em uma coleção de pares chave-valor formatados. Depois, usamos o método string.Join() para concatenar esses pares com “&” como separador.

Na sequência, concatenamos basePath e queryString para formar a URL completa e retornamos o resultado.

Neste exemplo, um dos principais desafios que enfrentamos é a codificação de URL e URI dos parâmetros de query string. Se tivermos um nome de autor com caracteres especiais, podemos acabar com uma URL malformada caso não codifiquemos esses caracteres ao passar o nome como parâmetro de query string.

Vejamos um exemplo de como codificar os parâmetros de query string:

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}";
}

Aqui, usamos o método HttpUtility.UrlEncode() para codificar tanto Key quanto Value de queryParams.

Por fim, vamos chamar o 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

Começamos inicializando um objeto Dictionary, que contém pares chave-valor que representam os parâmetros de query string da requisição à API. Passamos “George Orwell” como autor e “english” como idioma.

Em seguida, chamamos o método BuildUrlWithQueryStringUsingStringConcat(), passando a constante BaseApiUrl e a variável query para montar a URL completa.

A concatenação de strings não é a única forma manual de montar uma query string. Vale a pena conhecer outras duas: interpolação de strings e StringBuilder.Append().

Uso da classe UriBuilder

A classe UriBuilder do C# oferece uma forma poderosa e conveniente de criar instâncias de System.Uri e cópias modificadas de instâncias existentes. Podemos criar ou manipular URLs com vários componentes, como esquema, host, porta, caminho e query string.

Port vale -1 quando nenhuma porta é definida, e é isso que remove uma porta explícita do resultado; já ao analisar uma URL sem porta, obtemos a porta padrão do esquema.

A classe UriBuilder escapa os caracteres que são inválidos em um URI, como o espaço em Jane Austen, mas não escapa os delimitadores de query string &, = e # dentro de um valor; veja a próxima seção.

A referência de UriBuilder.Query da Microsoft diz qual padrão a propriedade segue: “As informações da consulta são escapadas de acordo com a RFC 2396.” Esse padrão reserva & e = para uso dentro de uma query string, então escapar de acordo com ele deixa esses caracteres exatamente onde estão. A cerquilha (#) é um caso mais complicado: a RFC 2396 faz dela o delimitador que encerra a query string e abre o fragmento, então ela também passa sem escape, e tudo o que vem depois dela deixa de fazer parte da query string.

The Web API Production Checklist, e-book gratuito em inglês

E-book gratuito

Sua Web API está pronta para produção?

33 itens para verificar antes de implantá-la, com a correção de cada um. Um PDF gratuito de 76 páginas para .NET 10.

O e-book está em inglês.

Baixe o checklist gratuito

PDF gratuito. Um único e-mail para enviá-lo. Cancele a inscrição quando quiser.

Vamos criar outro método na classe QueryStringHelper para demonstrar o uso da classe 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;
}

Começamos criando uma instância da classe UriBuilder e a inicializamos com a URL base da API. Em seguida, concatenamos os pares chave-valor usando o método string.Join() e definimos a propriedade Query da instância uriBuilder. Por fim, obtemos a URL completa da API acessando a propriedade Uri da instância de UriBuilder e, depois, a propriedade AbsoluteUri dela.

Então, vamos chamar o 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

Da mesma forma, inicializamos um objeto Dictionary que contém os parâmetros de query string. Depois, passamos a constante BaseApiUrl e a variável query ao método BuildUrlWithQueryStringUsingUriBuilder() para obter a URL completa. A classe UriBuilder codifica o valor do parâmetro author, que contém um espaço.

O UriBuilder codifica os valores dos parâmetros da query string?

Não. UriBuilder escapa apenas os caracteres que são inválidos em qualquer parte de um URI. Os delimitadores da query string são válidos em um URI, então passam direto.

Se atribuirmos author=Simon & Schuster à propriedade Query e lermos Uri.AbsoluteUri de volta, obtemos ?author=Simon%20&%20Schuster. O espaço virou %20. O e comercial continuou sendo um e comercial, então o destinatário lê um parâmetro chamado author com o valor Simon e um segundo chamado Schuster.

O caractere # é pior, e é o que um artigo sobre C# tem mais chance de encontrar. tag=C#&language=english trunca a URL na cerquilha: tudo o que vem depois dela vira o fragmento, o servidor recebe tag=C e language nunca chega.

Portanto, UriBuilder é um montador de URLs, e não um codificador de query strings. É a classe certa para esquema, host, porta e caminho, e ela espera que a string atribuída a Query já esteja codificada.

A correção cabe em uma linha. Monte a query string com algo que codifique e depois passe a string pronta para UriBuilder.

O diagrama acompanha um valor pelas duas APIs e para no ponto em que o servidor o analisa, porque é ali que a diferença aparece.

Diagrama que compara a codificação do valor Simon and Schuster por UriBuilder e por QueryHelpers.AddQueryString, mostrando que UriBuilder produz um segundo parâmetro fantasma.

Então, montamos a query string com QueryString.Create() (isso exige a referência ao framework Microsoft.AspNetCore.App, que adicionamos mais adiante) e deixamos que UriBuilder monte o resto da URL em volta dela:

public static string BuildUrlWithQueryStringUsingUriBuilderSafely(
    string basePath, Dictionary<string, string?> queryParams)
{
    var uriBuilder = new UriBuilder(basePath)
    {
        Query = QueryString.Create(queryParams).Value
    };

    return uriBuilder.Uri.AbsoluteUri;
}

A propriedade Value nos entrega a query string codificada com o ponto de interrogação inicial, que é exatamente o formato que a propriedade Query espera. Com author definido como Simon & Schuster e tag definido como C#, o resultado, ao ser analisado, traz de volta os valores que colocamos:

https://localhost:7220/api/Books?author=Simon%20%26%20Schuster&tag=C%23

Uso de HttpUtility.ParseQueryString

O método HttpUtility.ParseQueryString() faz parte do namespace System.Web no C#. Esse método é útil quando criamos ou manipulamos query strings em aplicações web.

Ele permite analisar uma query string existente e transformá-la em uma coleção de pares chave-valor, modificar esses pares e gerar uma nova query string.

Desmontar uma query string à mão significa dividir uma string em & e =, e as sobrecargas que fazem isso merecem ser conhecidas para quando não houver um método auxiliar disponível.

Vamos criar um novo método na classe QueryStringHelper para demonstrar essa 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());
}

Aqui, criamos uma NameValueCollection vazia usando o método HttpUtility.ParseQueryString(string.Empty).

Internamente, esse método cria uma instância de HttpQSCollection, que é uma subclasse não pública de NameValueCollection. Como é uma classe privada, precisamos usar essa forma não convencional de inicialização. A vantagem dessa coleção especial é o tratamento automático de valores null, junto com a codificação de URL correta de todos os pares chave-valor.

Atribuir um null pelo indexador grava um valor vazio (author=) em vez de omitir o parâmetro, e nenhuma exceção é lançada. Adicionar com Add(name, null), por outro lado, de fato descarta o parâmetro. QueryHelpers.AddQueryString() descarta um valor null vindo do dicionário.

Agora, vamos chamar o 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

Aqui, criamos os parâmetros de query string com o objeto Dictionary e chamamos o método BuildUrlWithQueryStringUsingParseQueryStringMethod() para obter a URL completa.

Uso de QueryHelpers.AddQueryString

QueryHelpers é uma classe utilitária do namespace Microsoft.AspNetCore.WebUtilities. Ela inclui o método AddQueryString(), que monta a query string adicionando ou anexando parâmetros a uma URL existente.

O método QueryHelpers.AddQueryString() garante a codificação de URL correta dos nomes e valores dos parâmetros, para que a URL fique bem formada.

Como ele anexa, este também é o método que usamos quando a URL já tem uma query string, e há um artigo inteiro sobre como anexar ou atualizar parâmetros em uma URL que já tem uma query string.

Como primeiro passo, vamos incluir Microsoft.AspNetCore.App como FrameworkReference no arquivo .csproj, dentro de um ItemGroup:

<FrameworkReference Include="Microsoft.AspNetCore.App" />

Adicionar essa referência garante que possamos usar o método QueryHelpers.AddQueryString() do namespace Microsoft.AspNetCore.WebUtilities. A mesma referência também nos dá acesso a QueryBuilder e QueryString. HttpUtility não precisa de nada: System.Web.HttpUtility faz parte do framework compartilhado base.

Agora, vamos criar um novo método para demonstrar o uso do método QueryHelpers.AddQueryString():

public static string BuildUrlWithQueryStringUsingAddQueryStringMethod(
    string basePath, Dictionary<string, string?> queryParams)
{
    return QueryHelpers.AddQueryString(basePath, queryParams);
}

Aqui, usamos o método QueryHelpers.AddQueryString() para gerar a query string. Passamos basePath e o dicionário queryParams como entrada e obtemos a URL completa.

Neste método, aceitamos especificamente um Dictionary<string, string?> com valores string anuláveis, porque o método QueryHelpers.AddQueryString() aceita valores anuláveis, o que dá flexibilidade para lidar com parâmetros de query string opcionais.

Em seguida, vamos chamar o 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

Da mesma forma, criamos um objeto Dictionary que contém os parâmetros de query string e passamos a variável query e a constante BaseApiUrl ao método BuildUrlWithQueryStringUsingAddQueryStringMethod() para montar a URL completa. Declaramos o objeto como Dictionary<string, string?> para corresponder ao parâmetro do método; um Dictionary<string, string> simples compila, mas gera o aviso CS8620.

Uso da classe QueryBuilder

A classe QueryBuilder faz parte do namespace Microsoft.AspNetCore.Http.Extensions e serve para montar uma query string. Em essência, a classe QueryBuilder permite montar uma query string adicionando pares chave-valor. Ela implementa a interface IEnumerable<KeyValuePair<String,String>>, o que significa que podemos iterar sobre os pares chave-valor que ela contém.

Vejamos um exemplo:

public static string BuildUrlWithQueryStringUsingQueryBuilderClass(
    string basePath, Dictionary<string, string> queryParams)
{
    var queryBuilder = new QueryBuilder(queryParams);

    return basePath + queryBuilder;
}

Aqui, criamos uma instância da classe QueryBuilder e passamos queryParams para o construtor, que inicializa a instância da classe QueryBuilder.

Quando concatenamos um objeto queryBuilder com uma string, o método ToString() da classe QueryBuilder é chamado implicitamente. No contexto da classe QueryBuilder, ela sobrescreve (override) o método ToString() para retornar a representação em query string dos pares chave-valor armazenados no objeto queryBuilder.

The Web API Production Checklist, e-book gratuito em inglês

E-book gratuito

Sua Web API está pronta para produção?

33 itens para verificar antes de implantá-la, com a correção de cada um. Um PDF gratuito de 76 páginas para .NET 10.

O e-book está em inglês.

Baixe o checklist gratuito

PDF gratuito. Um único e-mail para enviá-lo. Cancele a inscrição quando quiser.

Consequentemente, podemos concatenar o objeto queryBuilder com basePath para criar uma URL completa.

Em seguida, vamos chamar o 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

Aqui, inicializamos um objeto Dictionary e o passamos ao método BuildUrlWithQueryStringUsingQueryBuilderClass() para montar a URL completa.

Uso de QueryString.Create

O método QueryString.Create() é uma forma conveniente de criar um objeto de query string a partir de pares chave-valor.

O método QueryString.Create() oferece três sobrecargas. A primeira, Create(string name, string value), permite criar uma query string com um único par chave-valor.

A segunda sobrecarga, Create(IEnumerable<KeyValuePair<string, string?>> parameters), aceita uma coleção de pares chave-valor em que os valores são strings anuláveis.

Por fim, a terceira sobrecarga, Create(IEnumerable<KeyValuePair<string, StringValues>> parameters), recebe uma coleção de pares chave-valor em que os valores são do tipo StringValues.

Vamos criar um novo método na classe QueryStringHelper:

public static string BuildUrlWithQueryStringUsingCreateMethod(
    string basePath, Dictionary<string, string?> queryParams)
{
    var queryString = QueryString.Create(queryParams);

    return basePath + queryString;
}

Aqui, definimos um método que aceita um Dictionary<string, string?> com valores string anuláveis. Fizemos essa escolha porque a segunda sobrecarga do método QueryString.Create() aceita valores anuláveis.

Embora esse método não aceite explicitamente um Dictionary, ainda podemos passar um Dictionary para ele. Isso é possível porque Dictionary implementa a interface IEnumerable<KeyValuePair<string, string?>>. Em seguida, usamos o método QueryString.Create() e passamos o objeto de dicionário queryParams para montar uma query string.

Quando os parâmetros vêm de uma classe, e não de um dicionário, montar a query string a partir de um objeto em vez de um dicionário nos poupa de criar o dicionário à mão antes.

Por fim, vamos chamar o 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

Aqui, criamos um objeto Dictionary para representar os parâmetros de query string e chamamos o método BuildUrlWithQueryStringUsingCreateMethod() para formar a URL completa.

Como adicionar parâmetros de query string a uma requisição do HttpClient?

HttpClient não tem uma API para parâmetros de query string. GetAsync() recebe uma URL ou um Uri, então a query string precisa estar pronta antes de a chamada ser feita.

Em uma aplicação ASP.NET Core, o formato comum é QueryHelpers.AddQueryString() sobre um caminho relativo, passado para um cliente cujo BaseAddress já está configurado. O endereço base contém o host, a chamada contém os parâmetros e nenhum dos dois sabe do outro.

AddQueryString() anexa em vez de substituir. Chamado sobre um caminho que já tem uma query string, ele acrescenta parâmetros a ela, então /api/Books?page=2 com author adicionado vira /api/Books?page=2&author=Orwell.

É com esse comportamento de anexar que devemos tomar cuidado quando uma rota e um filtro contribuem, cada um, com parâmetros. Monte o dicionário inteiro primeiro e faça uma única chamada, em vez de encadear chamadas. E BaseAddress precisa da barra no final, senão a combinação de Uri descarta o último segmento do caminho.

Nenhuma etapa do envio da requisição codifica delimitadores. HttpClient envia a URL que passamos, então a codificação já aconteceu ou simplesmente não aconteceu.

O nosso exemplo já faz essa chamada. BooksApiService monta a URL e a passa direto para o 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();
}

A URL pronta é a única coisa que chega a HttpClient. Do outro lado da chamada, ler esses valores de volta no servidor é o trabalho inverso deste.

Em uma aplicação real, também não criaríamos o cliente nós mesmos com new; configurar o HttpClient pelo qual essa chamada passa é trabalho para IHttpClientFactory.

Qual método de query string é o mais seguro?

Duas das seis formas são inseguras por padrão. QueryHelpers.AddQueryString(), QueryString.Create(), QueryBuilder e a coleção ParseQueryString fazem a codificação percentual de nomes e valores. A concatenação de strings codifica quando lembramos de chamar HttpUtility.UrlEncode() nós mesmos. UriBuilder nunca codifica nenhum delimitador.

QueryHelpers.AddQueryString() é a escolha padrão dentro de uma aplicação ASP.NET Core: entram uma URL base e um dicionário, sai uma URL codificada, anexada a qualquer query string que a URL já tivesse.

HttpUtility.ParseQueryString(string.Empty) é a escolha para uma aplicação de console simples, porque System.Web.HttpUtility está no framework compartilhado base e não precisa de referência de framework.

As duas discordam sobre null. AddQueryString() descarta uma entrada do dicionário cujo valor é null; o indexador de ParseQueryString a mantém e escreve name=. Nenhuma das duas lança exceção.

Elas também discordam sobre espaços. HttpUtility.UrlEncode() escreve +, os auxiliares do ASP.NET Core escrevem %20 e as duas formas voltam a ser um espaço na decodificação.

QueryBuilder é esse mesmo codificador de novo, acessado uma chamada de Add() por vez, o que combina com uma query string montada ao longo de vários métodos, e não criada a partir de um único dicionário.

AbordagemCodifica & = # nos valores?Valor null resulta emNome repetidoQuando usar
Concatenação de strings + HttpUtility.UrlEncode()Só se nós mesmos chamarmos UrlEncode()o que escrevermosnós mesmos montamosprecisamos de controle total e aceitamos toda a responsabilidade
UriBuilder (atribuindo Query)Nãonão se aplicanós mesmos montamosmontar esquema, host, porta e caminho, não a query string
HttpUtility.ParseQueryString(string.Empty)Simname=chamar Add() duas vezes com o mesmo nomeuma aplicação de console sem FrameworkReference
QueryHelpers.AddQueryString()Simo parâmetro é descartadosobrecarga com StringValuesASP.NET Core, e quando a URL já pode ter uma query string
QueryBuilderSimnão se aplica (recebe string)Add(name, IEnumerable<string>)adicionar parâmetros um de cada vez
QueryString.Create()Simname=sobrecarga com StringValuesuma chamada a partir de um dicionário, sem URL base envolvida

Depois que a URL estiver montada, verificar se a URL que criamos é válida exige uma única chamada, e vale a pena fazê-la quando qualquer parte da URL veio de entrada do usuário.

Conclusão

Neste artigo, vimos várias abordagens para montar uma query string em C#. O método que escolhemos depende das nossas necessidades e preferências específicas.

Para concluir, podemos usar a concatenação de strings e outras técnicas manuais se precisarmos de uma forma simples de montar uma query string. No entanto, com a técnica de concatenação de strings, precisamos garantir que os nomes e valores dos parâmetros sejam codificados corretamente.

Por outro lado, se precisarmos montar query strings complexas ou lidar com muitos parâmetros, podemos usar um método mais robusto, como o método HttpUtility.ParseQueryString(), o método QueryHelpers.AddQueryString(), a classe QueryBuilder ou o método QueryString.Create().

Não precisamos codificar manualmente os parâmetros da query string ao usar qualquer um desses quatro métodos, porque eles fazem a codificação de URL internamente. UriBuilder é a exceção, e é ele que devemos combinar com um codificador em vez de passar uma query string sem codificação.

Testado com .NET 10.