用 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
就按常規(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)容如下圖所示:
5 使用 RDM
完成步驟 4 后盼铁,重新打開 RDM,即可正常顯示 Redis 中的 MessagePack 內(nèi)容了尝偎。