진정한 남자는 DB를 쓰지 않습니다.

아래 영상에 감명을 받아서,…

// .razor.cs
    [Parameter]
    [SupplyParameterFromQuery]
    public string? Data { get; set; }

    [Inject]
    public NavigationManager NavMan { get; set; } = null!;

    [Inject]
    public IJSRuntime JS { get; set; } = null!;

    private DataDto _dto = new(); 

    protected override void OnParametersSet()
    {
       if(Data != null)
       {
           _dto = DataDto.FromJson64(Data);
       }
    }

    private async Task OnSaveClickedAsync()
    {
       var url = NavMan.GetUriWithQueryParameter(nameof(Data), _dto.ToJson64());
       await JS.InvokeVoidAsync("navigator.clipboard.writeText", url);
       await JS.InvokeVoidAsync("alert", "데이터가 복사되었습니다.");
       NavMan.NavigateTo(url);
    }
    
class DataDto
{

   // properties..

    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;
    }

    public string ToJson64()
    {
        var jsonString = JsonSerializer.Serialize(this);
        var bytes = Encoding.UTF8.GetBytes(jsonString);
        var json64 = Convert.ToBase64String(bytes);
        return json64;
    }  
}

근데, DataDto 에 배열이 들어가니, URL이 몇 천자가 쉽게 넘어갑니다.
영상과는 다르게, 414 (URL 너무 김) 에러가 납니다.

진정한 남자는 여기에서 멈추지 않고, 압축해서 구겨 넣어 봅니다.

static class Ziper
{
    public static void CopyTo(Stream src, Stream dest)
    {
        byte[] bytes = new byte[4096];

        int cnt;

        while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
        {
            dest.Write(bytes, 0, cnt);
        }
    }

    public static byte[] Zip(string str)
    {
        var utf8Bytes = Encoding.UTF8.GetBytes(str);

        using var inStream = new MemoryStream(utf8Bytes);
        using var outStream = new MemoryStream();
        using (var gs = new GZipStream(outStream, CompressionMode.Compress))
        {
            CopyTo(inStream, gs);
        }

        return outStream.ToArray();
    }

    public static string Unzip(byte[] bytes)
    {
        using var inStream = new MemoryStream(bytes);
        using var outStream = new MemoryStream();
        using (var gs = new GZipStream(inStream, CompressionMode.Decompress))
        {
            CopyTo(gs, outStream);
        }

        return Encoding.UTF8.GetString(outStream.ToArray());
    }
}

DataDto 도 바꿔줍니다.

class DataDto
{
   // properties..

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

    public string ToJson64()
    {
        var jsonString = JsonSerializer.Serialize(this);
        // var bytes = Encoding.UTF8.GetBytes(jsonString));
        var bytes = Ziper.Zip(jsonString);
        var json64 = Convert.ToBase64String(bytes);
        return json64;
    }  
}

이제 URL이 반 이하로 줄어 414에러가 없어집니다… 는 뻥이고, Json 문자열을 줄이기 위해, 온갖 뻘짓을 하고 난 후에야 에러가 없어졌습니다.

로컬 저장소 또는 DB에 저장하는 하남자로 돌아 왔습니다.

6개의 좋아요

저도 저영상을 봤습니다 url 에 데이타를 저장한다는 개념 가능했구나 하며 놀랐는데
막상 실무에서 저같은 SI 쪽은 활용하기 좀 그렇지만 언제가 써먹을 수단 같긴 하니다

3개의 좋아요

서버 설정에 url 길이 제한에 대한 설정이 있었던거 같아요

3개의 좋아요

남성 호르몬이 넘치다 보니 구겨 넣을 생각만 했지, 그런 것까지 생각을 못했군요. ㅋㅋ

5개의 좋아요

저도 지금 서비스중인 blazor에 쿼리 스트링을 많이 활용하는 편인데
긴 데이터를 압축해서 넣는다니… 진정 상남자시군요??

2개의 좋아요

뭐 이런 시도가 처음은 아닌 것이, 과거에 ASP.NET Web Form에서는 View State라고 하는 BASE64로 폼 상태 데이터를 인코딩해서 데이터 뭉치로 만들어 놓고 전송때마다 태그에 얹어서 보내는 만행(?)을 저지르던 때도 있었습니다. 복잡한 비즈니스 애플리케이션들은 이 뷰스테이트 데이터 한 방에 1~2MB 이상의 트래픽을 주고 받게끔 덩치를 키우는 경우도 있었죠. :thinking: (URL에 query string을 넣든, 폼 태그에 데이터를 넣든 사용자 인터페이스에만 차이가 생길 뿐이지 본질적으로는 같습니다.)

그리고 URL을 받아서 해석하는 브라우저나 서버가 무엇이냐에 따라서 해석 방법이 제각기 모두 다르기 때문에, 말씀하신것처럼 URL이 잘리거나 414 오류가 발생할 수 있는데, 문제는 URL 최대 길이라는 것이 표준화된 적이 한 번도 없기 때문에 "상식선의 상한선"을 정의해서 알아서 관리해야 하는 어려움도 있겠습니다.

URL length: how long can a URL be? - SISTRIX

5개의 좋아요