출처 : 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 형식을 보장한다.
'C#' 카테고리의 다른 글
C#] LINQ - Any(), Exists() 함수 차이 (0) | 2023.11.15 |
---|---|
C#] Discard Variable '_' 사용법 (0) | 2023.11.14 |
C#] String 검색 함수, 성능 비교 (0) | 2023.10.23 |
C#] method signature - generic type, specific type (0) | 2023.09.15 |
C# 9.0] init keyword, record, with-expression (0) | 2023.09.05 |
댓글