input 을 거친 base64 파싱 하기

아래의 글과 관련해서

진정한 남자는 DB를 쓰지 않습니다. - :thread: Slog - 닷넷데브 (dotnetdev.kr)

Uri 를 Base64로 엔코딩하여, 길이를 손해보고 호환성을 꾀하는 것은 흔히 쓰는 방법입니다.

문제는 C#의 문자열 처리에 있습니다.

사용자가 Uri 를 복사해서, 주소창에 넣으면 아무런 문제가 없습니다.
그런데, Uri에 포함된 쿼리 매개변수(Data)의 값(Base64 문자열) 에 대한 유효성 검사를 하기 위해,

주소창이 아닌, input form 에 붙여넣기를 하게 하고, 폼에 입력된 값을 파싱하여, 데이터 부분만 추출한 후에, 아래 메서드를 호출하면 엔코딩 예외가 발생합니다.

    public static DataDto? FromJson64(string json64)
    {
        var bytes = Convert.FromBase64String(json64); // 예외 발생
        var utf8String = Encoding.UTF8.GetString(bytes);
        var dto = JsonSerializer.Deserialize<DataDto>(utf8String);
        return dto;
    }

이 예외는 input 에 입력된 문자열을 그대로 코드로 읽거나, 문자열을 Substring 하는 순간, 문자열의 엔코딩이 C#의 utf-16 으로 변경되기 때문입니다.

이 utf-16 문자열을 Base64로 인식하는 것이 쉽지 않더군요.

(아시는 분 댓글 부탁드립니다)

결국 찾아낸 해결책은 Uri 클래스와
Uri Class (System) | Microsoft Learn

QueryHelpers 입니다.

NuGet Gallery | Microsoft.AspNetCore.WebUtilities 2.2.0

    private void OnParseClicked()
    {
        Dictionary<string, StringValues> queryDic = new();

        try
        {
            var uri = new Uri(_uriPasted);
            var allQueries = uri.Query;
            queryDic = QueryHelpers.ParseQuery(allQueries);
        }
        catch (Exception) 
        {
            _errorMessage = "입력된 값이 올바른 주소 형식이 아닙니다.";
            return;
        }

        if (queryDic.TryGetValue("Data", out var json64))
        {
            if(StringValues.IsNullOrEmpty(json64) is false)
            {
               try
               {
                   var dto = DataDto.FromJson64(json64!);
               }
               catch (Exception)
               {
                   _errorMessage = SchedulePageResx["데이터가 오염되었습니다."];
               }

               return;
            }
        }

        _errorMessage = SchedulePageResx["데이터가 없습니다."];
    }
3개의 좋아요