Microsoft MVP성태의 닷넷 이야기
닷넷: 2185. C# - object를 QueryString으로 직렬화하는 방법 [링크 복사], [링크+제목 복사],
조회: 15072
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

C# - object를 QueryString으로 직렬화하는 방법

간혹 QueryString 문자열을 구해야 하는 경우가 있는데요, 물론 검색해 보면 많은 코드들이 있습니다.

How do I serialize an object into query-string format?
; https://stackoverflow.com/questions/6848296/how-do-i-serialize-an-object-into-query-string-format

이에 기반해 다음과 같이 간단하게 만들 수 있고,

internal static class ObjectExtension
{
    static ConcurrentDictionary<Type, PropertyInfo[]> _typePropertyCache = new ConcurrentDictionary<Type, PropertyInfo[]>();

    public static string ToQueryString(this object obj)
    {
        Type type = obj.GetType();

        if (_typePropertyCache.TryGetValue(type, out var propInfo) == false)
        {
            propInfo = (from prop in type.GetProperties()
                       where prop.CanRead == true
                       select prop).ToArray();

            _typePropertyCache.TryAdd(type, propInfo);
        }

        var queryArray = from prop in propInfo
                        select prop.Name + "=" + HttpUtility.UrlEncode(prop.GetValue(obj, null)?.ToString());

        return string.Join("&", queryArray);
    }
}

이런 식으로 쓸 수 있습니다.

namespace ConsoleApp1;

internal class Program
{
    static void Main(string[] args)
    {
        Test v = new Test
        {
            Name = "test",
            Age = 10,
            Birthday = DateTime.Now
        };

        Console.WriteLine(v.ToQueryString());
        // 출력 결과: Name=test&Age=10&Birthday=2023-12-19+%ec%98%a4%ed%9b%84+11%3a08%3a57
    }
}

public class Test
{
    public string Name { get; set; } = "";
    public int Age { get; set; }
    public DateTime Birthday { get; set; }
}

그런데, 혹시 QueryString을 위한 Source Generator라도 있지 않을까요? 아쉽게도 ^^ 검색했지만 찾을 수 없었습니다. 만들자니 귀찮군요, 요즘 너무 야크 털을 깎아서,,, 그렇다면 혹시나 차선책으로 기존의 Serializer처럼 타입마다 전용 Writer를 동적으로 생성해 사용하는 것이 있지 않을까... 싶었는데요, 오호~~~ 정말 있습니다. ^^

WebSerializer
; https://github.com/Cysharp/WebSerializer

사용법은 역시 간단합니다.

using Cysharp.Web; // Install-Package WebSerializer

namespace ConsoleApp1;

internal class Program
{
    static void Main(string[] args)
    {
        Test v = new Test
        {
            Name = "test",
            Age = 10,
            Birthday = DateTime.Now
        };

        Console.WriteLine(WebSerializer.ToQueryString(v));
    }
}

당연히 성능도 좋을 텐데요, 제 컴퓨터에서 저 2개의 소스 코드를 1_000_000번 루프를 돌렸더니,

[ObjectExtension.ToQueryString]
00:00:00.8749938

[WebSerializer.ToQueryString]
00:00:00.3657905

WebSerializer가 2.4배 가까이 빠른 속도를 보입니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 12/19/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 16  17  18  19  20  21  22  23  24  25  26  27  28  [29]  30  ...
NoWriterDateCnt.TitleFile(s)
13308정성태4/4/202317224스크립트: 47. 파이썬의 time.time() 실숫값을 GoLang / C#에서 사용하는 방법 [1]
13307정성태4/4/202315184.NET Framework: 2106. C# - .NET Core/5+ 환경의 Windows Forms 응용 프로그램에서 HINSTANCE 구하는 방법
13306정성태4/3/202315430Windows: 243. Win32 - 윈도우(cbWndExtra) 및 윈도우 클래스(cbClsExtra) 저장소 사용 방법
13305정성태4/1/202317579Windows: 242. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (쉬운 버전) [1]파일 다운로드1
13304정성태3/31/202317703VS.NET IDE: 181. Visual Studio - C/C++ 프로젝트에 application manifest 적용하는 방법
13303정성태3/30/202315402Windows: 241. 환경 변수 %PATH%에 DLL을 찾는 규칙
13302정성태3/30/202316732Windows: 240. RDP 환경에서 바뀌는 %TEMP% 디렉터리 경로
13301정성태3/29/202317072Windows: 239. C/C++ - Windows 10 Version 1607부터 지원하는 /DEPENDENTLOADFLAG 옵션 [1]파일 다운로드1
13300정성태3/28/202316417Windows: 238. Win32 - Modal UI 창에 올바른 Owner(HWND)를 설정해야 하는 이유
13299정성태3/27/202316268Windows: 237. Win32 - 모든 메시지 루프를 탈출하는 WM_QUIT 메시지
13298정성태3/27/202315269Windows: 236. Win32 - MessageBeep 소리가 안 들린다면?
13297정성태3/26/202317530Windows: 235. Win32 - Code Modal과 UI Modal
13296정성태3/25/202316687Windows: 234. IsDialogMessage와 협업하는 WM_GETDLGCODE Win32 메시지 [1]파일 다운로드1
13295정성태3/24/202316520Windows: 233. Win32 - modeless 대화창을 modal처럼 동작하게 만드는 방법파일 다운로드1
13294정성태3/22/202316425.NET Framework: 2105. LargeAddressAware 옵션이 적용된 닷넷 32비트 프로세스의 가용 메모리 - 두 번째
13293정성태3/22/202315553오류 유형: 853. dumpbin - warning LNK4048: Invalid format file; ignored
13292정성태3/21/202316163Windows: 232. C/C++ - 일반 창에도 사용 가능한 IsDialogMessage파일 다운로드1
13291정성태3/20/202316190.NET Framework: 2104. C# Windows Forms - WndProc 재정의와 IMessageFilter 사용 시의 차이점
13290정성태3/19/202317274.NET Framework: 2103. C# - 윈도우에서 기본 제공하는 FindText 대화창 사용법파일 다운로드1
13289정성태3/18/202315370Windows: 231. Win32 - 대화창 템플릿의 2진 리소스를 읽어들여 자식 윈도우를 생성하는 방법파일 다운로드1
13288정성태3/17/202316156Windows: 230. Win32 - 대화창의 DLU 단위를 pixel로 변경하는 방법파일 다운로드1
13287정성태3/16/202316390Windows: 229. Win32 - 대화창 템플릿의 2진 리소스를 읽어들여 윈도우를 직접 띄우는 방법파일 다운로드1
13286정성태3/15/202316973Windows: 228. Win32 - 리소스에 포함된 대화창 Template의 2진 코드 해석 방법
13285정성태3/14/202315728Windows: 227. Win32 C/C++ - Dialog Procedure를 재정의하는 방법 [2]파일 다운로드1
13284정성태3/13/202314820Windows: 226. Win32 C/C++ - Dialog에서 값을 반환하는 방법파일 다운로드1
13283정성태3/12/202312641오류 유형: 852. 파이썬 - TypeError: coercing to Unicode: need string or buffer, NoneType found
... 16  17  18  19  20  21  22  23  24  25  26  27  28  [29]  30  ...