自己實現(xiàn) RDM Formatter(MessagePack/.NET 6.0)

用 RDM(Redis Desktop Manager)有一段時間了,本想找個現(xiàn)成的用 .NET 反序列化 MessagePack 的 Formatter柱查,但是資源很少,好不容易找的一個云石,還不能用唉工,所以,就自己實現(xiàn)了 RDM MessagePack Formatter汹忠。

注意:本文用 C# 只實現(xiàn)了 MessagePack 的反序列化和在 RDM 中顯示淋硝,若要通過 RDM 以 MessagePack 序列化后添加到 Redis 中雹熬,目前還未實現(xiàn)。

本文涉及的產(chǎn)品和組件

  1. RDM(Redis Desktop Manager)2021.8 GitHub
  2. RDM Formatter 說明文檔 | GitHub
  3. System.Text.Json (.NET 6.0 / Visual Studio 2022 / Windows)
  4. MessagePack 2.3.85 GitHub | NuGet

1 安裝 RDM

就按常規(guī)安裝好 RDM 后谣膳,在安裝目錄中竿报,找到 formatters 目錄,在里面新建一個目錄(名稱可自定義参歹,方便記憶就好仰楚,最好用字母),在步驟 4 要用犬庇。

2 建立項目

用 VS 建立一個項目(類庫或控制臺應用都可以)僧界,項目(RDMMsgPackFormatter)結構如下所示:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="MessagePack" Version="2.3.85" />
    </ItemGroup>

    <ItemGroup>
        <None Update="usage.json">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
    </ItemGroup>

</Project>

RDM Formatter 需要一個配置文件,叫 usage.json臭挽,建議用 UTF-8 格式捂襟,全部內(nèi)容如下所示:

[ "dotnet", "RDMMsgPackFormatter.dll" ]

注意:數(shù)組第二項,填入 dll 文件欢峰,請勿填入 exe 文件T岷伞!纽帖!

3 擼碼

在項目中宠漩,添加 Program.cs 文件,完整內(nèi)容如下:

using MessagePack;

using System.Text.Json;
using System.Text.Json.Serialization;

namespace RDMMsgPackFormatter;

public class Program
{
    // System.Text.Json 序列化配置
    private static readonly JsonSerializerOptions _jsonOpts;

    static Program()
    {
        _jsonOpts = new JsonSerializerOptions
        {
            IncludeFields = true,
            AllowTrailingCommas = true,
            PropertyNameCaseInsensitive = true,
            ReadCommentHandling = JsonCommentHandling.Skip,
            DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };
    }

    static void Main(string[] args)   // 主入口
    {
        if (args is { Length: > 0 })
        {
            switch (args[0])
            {
                case "info":   // Formatter 基本信息標識
                    Info();
                    break;
                case "decode":   // Formatter 反序列化標識
                    Decode();
                    break;
                case "encode":   // Formatter 序列化標識
                    // 暫未實現(xiàn)
                    break;
            }
        }
    }

    private static void Info()
    {
        // 用 Console.Write() 對 RDM 輸出要顯示的內(nèi)容
        Console.Write(JsonSerializer.Serialize(new FormatterInfo(), _jsonOpts));
    }

    private static void Decode()
    {
        try
        {
            char[] charsInput;
            byte[] bytes;
            string input, json;

            // 通過 Console.ReadLine() 讀取 RDM 輸入的內(nèi)容
            while ((input = Console.ReadLine()) is not null)
            {
                // RDM 輸入的內(nèi)容懊直,是:binary-data-encoded-with-base64
                // 以下用 MessagePackSerializer.ConvertToJson(byte[]) 將輸入的內(nèi)容轉換為 json 字符串
                charsInput = input.ToCharArray();
                bytes = Convert.FromBase64CharArray(charsInput, 0, charsInput.Length);
                json = MessagePackSerializer.ConvertToJson(bytes);

                // 用 Console.Write() 輸出的內(nèi)容扒吁,格式如下:
                // {
                //     "output": "要在 RDM 中顯示的可讀的內(nèi)容"
                //     "read-only": true(結果不可編輯)false(結果可編輯)
                //     "format": "plain_text" 或 "json"
                // }
                Console.Write(JsonSerializer.Serialize(new FormatterDecode(json, NeedJsonFormat(json)), _jsonOpts));
            }
        }
        catch (Exception e)
        {
            // 反序列化失敗的異常信息
            Console.Write(JsonSerializer.Serialize(new FormatterError(e.Message), _jsonOpts));
        }
    }

    // 該方法,主要是用于判斷字符串內(nèi)容是否是 json 對象或 json 數(shù)組室囊,方便最終格式化輸出并顯示
    private static bool NeedJsonFormat(string content)
    {
        var doc = JsonDocument.Parse(content);
        return doc.RootElement.ValueKind is JsonValueKind.Object or JsonValueKind.Array;
    }
}

/// <summary>
/// Formatter 信息的實體類
/// </summary>
public class FormatterInfo
{
    public string Version { get; private set; } = ".NET 6.0";

    public string Description { get; private set; } = "Dotnet MessagePack formatter";

    /// <summary>
    /// true:默認值雕崩,不顯示在添加數(shù)據(jù)的對話框的下拉菜單中
    /// false:將顯示在添加數(shù)據(jù)的對話框的下拉菜單中
    /// </summary>
    [JsonPropertyName("read-only")]
    public bool ReadOnly { get; private set; } = false;
}

/// <summary>
/// Formatter 序列化/反序列化失敗的實體類
/// </summary>
public class FormatterError
{
    public FormatterError(string error)
    {
        Error = error;
    }

    public string Error { get; private set; }
}

/// <summary>
/// Formatter 返序列化輸出的實體類
/// </summary>
public class FormatterDecode
{
    public FormatterDecode(string output, bool isJson = false)
    {
        Output = output;
        Format = isJson ? "json" : "plain_text";
    }

    /// <summary>
    /// 輸出到 RDM 的內(nèi)容
    /// </summary>
    public string Output { get; private set; }

    /// <summary>
    /// 輸出到 RDM 的內(nèi)容是否可以編輯
    /// </summary>
    [JsonPropertyName("read-only")]
    public bool ReadOnly { get; private set; } = true;

    /// <summary>
    /// 輸出到 RDM 的內(nèi)容格式化方式
    /// (僅支持 plain_text 和 json 兩種方式)
    /// </summary>
    public string Format { get; private set; }
}

4 安裝到 RDM 中

擼完碼后編譯,將編譯得到的所有文件(exe 除外)拷貝到步驟 1 中新建的目錄內(nèi)融撞,內(nèi)容如下圖所示:

步驟 1 新建目錄內(nèi)的全部內(nèi)容

5 使用 RDM

完成步驟 4 后盼铁,重新打開 RDM,即可正常顯示 Redis 中的 MessagePack 內(nèi)容了尝偎。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饶火,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子致扯,更是在濱河造成了極大的恐慌趁窃,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件急前,死亡現(xiàn)場離奇詭異,居然都是意外死亡瀑构,警方通過查閱死者的電腦和手機裆针,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門刨摩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人世吨,你說我怎么就攤上這事澡刹。” “怎么了耘婚?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵罢浇,是天一觀的道長。 經(jīng)常有香客問我沐祷,道長嚷闭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任赖临,我火速辦了婚禮胞锰,結果婚禮上,老公的妹妹穿的比我還像新娘兢榨。我一直安慰自己嗅榕,他們只是感情好,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布吵聪。 她就那樣靜靜地躺著凌那,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吟逝。 梳的紋絲不亂的頭發(fā)上帽蝶,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音澎办,去河邊找鬼嘲碱。 笑死,一個胖子當著我的面吹牛局蚀,可吹牛的內(nèi)容都是我干的麦锯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼琅绅,長吁一口氣:“原來是場噩夢啊……” “哼扶欣!你這毒婦竟也來了?” 一聲冷哼從身側響起千扶,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤料祠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后澎羞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體髓绽,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年妆绞,在試婚紗的時候發(fā)現(xiàn)自己被綠了顺呕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枫攀。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖株茶,靈堂內(nèi)的尸體忽然破棺而出来涨,到底是詐尸還是另有隱情,我是刑警寧澤启盛,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布蹦掐,位于F島的核電站,受9級特大地震影響僵闯,放射性物質(zhì)發(fā)生泄漏卧抗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一棍厂、第九天 我趴在偏房一處隱蔽的房頂上張望颗味。 院中可真熱鬧,春花似錦牺弹、人聲如沸浦马。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晶默。三九已至,卻和暖如春航攒,著一層夾襖步出監(jiān)牢的瞬間磺陡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工漠畜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留币他,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓憔狞,卻偏偏與公主長得像蝴悉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子瘾敢,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容