아래의 글과 관련해서
진정한 남자는 DB를 쓰지 않습니다. - 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["데이터가 없습니다."];
}