본문 바로가기
C#

C#] Query String 만드는 방법

by Fastlane 2023. 11. 7.
728x90
반응형

출처 : How to Build a Query String for a URL in C#? (code-maze.com)

웹 개발에서 query string은 clients와 servers 사이에 데이터를 교환하는 중요한 역할을 한다. 

C#에서 어떻게 query string을 만들 수 있는지 알아보자. 

 

Query String이란?

query string은 URL끝에서 ? 마크 다음에 이어지는 문자열이다. & 문자에 의해 나눠지는 key-value pairs로 구성된다. 

 

다음 query string을 살펴보자. 

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

 

여기서 url은 https://test.com/api/Books base address로 시작되며 ? 마크 다음에 query string이 시작된다. 

author는 key이고 rowling은 value이다. &가 두번째 key-value pair인 language=english로부터 구분시킨다. 

 

Query String 만드는 방법

  • String Concatenation
  • UriBuilder
  • ParseQueryString
  • QueryHelpers
  • QueryBuilder
  • QueryString.Create
using System.Web;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.WebUtilities;


namespace BuildQueryString;


public static class QueryStringHelper
{
    public static string BuildUrlWithQueryStringUsingStringConcat(string basePath, Dictionary<string, string> queryParams)
    {
        //string concatenation은 가장 기본적인 방법 중 하나이다. 복잡한 쿼리나 많은 parameters를 다루기에는 무거운 편이다.
        var queryString = string.Join("&", queryParams.Select(kvp => $"{HttpUtility.UrlEncode(kvp.Key)}={HttpUtility.UrlEncode(kvp.Value)}"));


        return $"{basePath}?{queryString}";
    }


    public static string BuildUrlWithQueryStringUsingUriBuilder(string basePath, Dictionary<string, string> queryParams)
    {
        //UriBuilder class는 System.Uri instances를 다루기 좋은 방법을 제공한다.
        var uriBuilder = new UriBuilder(basePath) //base URL로 초기화한다.
        {
            //uriBuilder instance의 Query property를 set한다.
            Query = string.Join("&", queryParams.Select(kvp => $"{kvp.Key}={kvp.Value}"))
        };


        return uriBuilder.Uri.AbsoluteUri;
    }


    public static string BuildUrlWithQueryStringUsingParseQueryStringMethod(string basePath, Dictionary<string, string> queryParams)
    {
        //HttpUtility namespace : System.Web
        //존재하는 query string을 collection으로 parse하고, 수정하고, 새로운 query string을 만드는데 유용하다.
        var query = HttpUtility.ParseQueryString(string.Empty); //create empty NameValueCollection


        foreach(var dict in queryParams)
        {
            query[dict.Key] = dict.Value;
        }
       
        return string.Join("?", basePath, query.ToString());
    }


    public static string BuildUrlWithQueryStringUsingAddQueryStringMethod(string basePath, Dictionary<string, string?> queryParams)
    {
        //QueryHelpers namespace : Microsoft.AspNetCore.WebUtilities
        //존재하는 url에 parameters를 추가함으로 query string을 만든다.
        //Microsoft.AspNetCore를 사용하기 위해 .csproj file의 ItemGroup에 아래를 추가한다.
        //<FrameworkReference Include="Microsoft.AspNetCore.App" />
        return QueryHelpers.AddQueryString(basePath, queryParams);
    }


    public static string BuildUrlWithQueryStringUsingQueryBuilderClass(string basePath, Dictionary<string, string> queryParams)
    {
        //QueryBuilder namespace : Micosoft.AspNetCore.Http.Extensions
        var queryBuilder = new QueryBuilder(queryParams);


        return basePath + queryBuilder;
    }


    public static string BuildUrlWithQueryStringUsingCreateMethod(string basePath, Dictionary<string, string?> queryParams)
    {
        //QueryString namespace : Microsoft.AspNetCore.Http
        var queryString = QueryString.Create(queryParams);


        return basePath + queryString;
    }


   


}

 

 

namespace BuildQueryString;


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


    public BooksApiService()
    {


    }


    public string GetWithQueryParamsUsingStringConcatenation(string author, string language)
    {
        var query = new Dictionary<string, string>
        {
            {"author", author},
            {"language", language}
        };


        return QueryStringHelper.BuildUrlWithQueryStringUsingStringConcat(BaseApiUrl, query);
    }


    public string GetWithQueryParamsUsingUriBuilder(string author, string language)
    {
        var query = new Dictionary<string, string>
        {
            {"author", author},
            {"language", language}
        };


        return QueryStringHelper.BuildUrlWithQueryStringUsingUriBuilder(BaseApiUrl, query);
    }


    public string GetWithQueryParamsUsingParseQueryStringMethod(string author, string language)
    {
        var query = new Dictionary<string, string>
        {
            {"author", author},
            {"language", language}
        };


        return QueryStringHelper.BuildUrlWithQueryStringUsingParseQueryStringMethod(BaseApiUrl, query);
    }


    public string GetWithQueryParamsUsingAddQueryStringMethod(string author, string language)
    {
        var query = new Dictionary<string, string?>
        {
            {"author", author},
            {"language", language}
        };


        return QueryStringHelper.BuildUrlWithQueryStringUsingAddQueryStringMethod(BaseApiUrl, query);
    }


    public string GetWithQueryParamsUsingQueryBuilderClass(string author, string language)
    {
        var query = new Dictionary<string, string>
        {
            {"author", author},
            {"language", language}
        };


        return QueryStringHelper.BuildUrlWithQueryStringUsingQueryBuilderClass(BaseApiUrl, query);
    }


    public string GetWithQueryParamsUsingCreateMethod(string author, string language)
    {
        var query = new Dictionary<string, string?>
        {
            {"author", author},
            {"language", language}
        };


        return QueryStringHelper.BuildUrlWithQueryStringUsingCreateMethod(BaseApiUrl, query);
    }
}

테스트 해보자. 

Console.WriteLine(test.GetWithQueryParamsUsingStringConcatenation("George Orwell", "english"));
Console.WriteLine(test.GetWithQueryParamsUsingUriBuilder("George Orwell", "english"));
Console.WriteLine(test.GetWithQueryParamsUsingParseQueryStringMethod("George Orwell", "english"));
Console.WriteLine(test.GetWithQueryParamsUsingAddQueryStringMethod("George Orwell", "english"));
Console.WriteLine(test.GetWithQueryParamsUsingQueryBuilderClass("George Orwell", "english"));
Console.WriteLine(test.GetWithQueryParamsUsingCreateMethod("George Orwell", "english"));



output : 
https://localhost:7220/api/Books?author=George+Orwell&language=english
https://localhost:7220/api/Books?author=George%20Orwell&language=english
https://localhost:7220/api/Books?author=George+Orwell&language=english
https://localhost:7220/api/Books?author=George%20Orwell&language=english
https://localhost:7220/api/Books?author=George%20Orwell&language=english
https://localhost:7220/api/Books?author=George%20Orwell&language=english

 

 

결론

C#에서 query string을 만드는 여러 방법을 살펴보았다. 우리의 필요나 기호에 따라 함수를 선택하면 된다. 

 

query string을 만들기 위해 직관적인 방법이 필요하다면 string concatenation이나 다른 방법을 사용할 수 있다. 하지만, string concatenation은 반드시 parameter names과 values의 encode를 적절히 해줘야 한다. 

 

반면에, 복잡하거나 많은 parameters를 다루려면, UriBuilder class, HttpUtility.ParseQueryString(), QueryHelpers.AddQueryString(), QueryBuilder class, QueryString.Create() 함수를 사용할 수 있다. 이러한 함수들에는 encode가 필요하지 않다. 내부적으로 url encoding을 다루며, 안전하고 정확한 URL 형식을 보장한다. 

728x90
반응형

댓글