Closed RoyLi-Pvt closed 2 weeks ago
计划着在2.0版本会处理这个问题。
那就盼望2.0早日Release了~~ 其实我已经完成了初步的移植,测试是全Pass的,但是由于赶时间所以修改的很凌乱不适合提PR😂. 总体上移植还是很简单的,只是需要注意一下几点
System.Text.Json和Json.Net的默认序列化行为是不一样的所以需要给System.Text.Json额外指定一个JsonSerializerOptions来确保一致性,类似下面这样:
internal static JsonSerializerOptions JsonOpt = new()
{
PropertyNameCaseInsensitive = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
IgnoreReadOnlyFields = false,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
IncludeFields = true
};
在ObjectUtil中需要在序列化时引入这个Option. 不过我没严格的测试具体是那个选项会影响功能实现,只是参考文档把两边的默认行为尽量修改为一致.
基于System.Text.Json的API,我重写了DefaultJsonConfigurationStringParser,以下两个函数由NewBing辅助给出(包括注释😂):
private IDictionary<string, string> ParseString(string input)
{
var Doc = JsonDocument.Parse(input);
SortedDictionary<string, string> SortedDict = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var Pairs = this.GetKeyValuePairs(Doc.RootElement, SortedDict);
foreach (var Pair in Pairs)
{
SortedDict.Add(Pair.Key, Pair.Value);
}
return SortedDict;
}
private IEnumerable<KeyValuePair<string, string>> GetKeyValuePairs(JsonElement element, SortedDictionary<string, string> SortedDict, string path = "")
{
// 如果元素是对象,则遍历其属性
if (element.ValueKind == JsonValueKind.Object)
{
foreach (var property in element.EnumerateObject())
{
// 拼接属性名称到路径
string subPath = path + "/" + property.Name;
// 递归调用
foreach (var pair in GetKeyValuePairs(property.Value, SortedDict, subPath))
{
yield return pair;
}
}
}
// 如果元素是数组,则遍历其元素
else if (element.ValueKind == JsonValueKind.Array)
{
int index = 0;
foreach (var item in element.EnumerateArray())
{
// 拼接索引到路径
string subPath = path + ":" + index;
// 递归调用
foreach (var pair in GetKeyValuePairs(item, SortedDict, subPath))
{
yield return pair;
}
index++;
}
}
// 否则,元素是一个基本值,直接返回键值对
else
{
var Pair = new KeyValuePair<string, string>(path.TrimStart('/'), element.ToString());
yield return Pair;
}
}
grpc-dotnet不支持以new List<Grpc.Core.ChannelOption>
的形式传入自定义ChannelOption(本身在grpc定义中ChannelOption也只能在可选值内选择),此外语法和远程地址的格式也有调整所以grpc初始化Channel修改为一下语句:
Channel = GrpcChannel.ForAddress($"http://{serverInfo.ServerIp}:{port}",
new GrpcChannelOptions { Credentials = ChannelCredentials.Insecure});
除了上述几点以外都是非常常规的改动了,替换Attribute之类的.
支持迁移到grpc-dotnet,这样能同时解决.net core sdk不支持m1芯片的问题 #251
那就盼望2.0早日Release了~~ 其实我已经完成了初步的移植,测试是全Pass的,但是由于赶时间所以修改的很凌乱不适合提PR😂. 总体上移植还是很简单的,只是需要注意一下几点
System.Text.Json和Json.Net的默认序列化行为是不一样的所以需要给System.Text.Json额外指定一个JsonSerializerOptions来确保一致性,类似下面这样:
internal static JsonSerializerOptions JsonOpt = new() { PropertyNameCaseInsensitive = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, IgnoreReadOnlyFields = false, DefaultIgnoreCondition = JsonIgnoreCondition.Never, IncludeFields = true };
在ObjectUtil中需要在序列化时引入这个Option. 不过我没严格的测试具体是那个选项会影响功能实现,只是参考文档把两边的默认行为尽量修改为一致.
基于System.Text.Json的API,我重写了DefaultJsonConfigurationStringParser,以下两个函数由NewBing辅助给出(包括注释😂):
private IDictionary<string, string> ParseString(string input) { var Doc = JsonDocument.Parse(input); SortedDictionary<string, string> SortedDict = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase); var Pairs = this.GetKeyValuePairs(Doc.RootElement, SortedDict); foreach (var Pair in Pairs) { SortedDict.Add(Pair.Key, Pair.Value); } return SortedDict; }
private IEnumerable<KeyValuePair<string, string>> GetKeyValuePairs(JsonElement element, SortedDictionary<string, string> SortedDict, string path = "") { // 如果元素是对象,则遍历其属性 if (element.ValueKind == JsonValueKind.Object) { foreach (var property in element.EnumerateObject()) { // 拼接属性名称到路径 string subPath = path + "/" + property.Name; // 递归调用 foreach (var pair in GetKeyValuePairs(property.Value, SortedDict, subPath)) { yield return pair; } } } // 如果元素是数组,则遍历其元素 else if (element.ValueKind == JsonValueKind.Array) { int index = 0; foreach (var item in element.EnumerateArray()) { // 拼接索引到路径 string subPath = path + ":" + index; // 递归调用 foreach (var pair in GetKeyValuePairs(item, SortedDict, subPath)) { yield return pair; } index++; } } // 否则,元素是一个基本值,直接返回键值对 else { var Pair = new KeyValuePair<string, string>(path.TrimStart('/'), element.ToString()); yield return Pair; } }
- grpc-dotnet不支持以
new List<Grpc.Core.ChannelOption>
的形式传入自定义ChannelOption(本身在grpc定义中ChannelOption也只能在可选值内选择),此外语法和远程地址的格式也有调整所以grpc初始化Channel修改为一下语句:Channel = GrpcChannel.ForAddress($"http://{serverInfo.ServerIp}:{port}", new GrpcChannelOptions { Credentials = ChannelCredentials.Insecure});
除了上述几点以外都是非常常规的改动了,替换Attribute之类的.
您好: 是否可以提供一下您从 Newtonsoft.Json 库迁移到 System.Text.Json 库的代码嘛?我们最近也在使用 Nacos,却发现原有的包中的 JSON 序列化库和我们的冲突了,导致很多时候不知道用那个。 谢谢!
额 @Net-18K 迁移到 System.Text.Json的代码在你引用的那个回复里面基本上已经全提供了啊~~ 剩下的只是批量替换Json.Net的Attribute为System.Text.Json的版本或者将实际调用的函数由Json.Net切换到System.Text.Json对应实现而已
那就盼望2.0早日Release了~~ 其实我已经完成了初步的移植,测试是全Pass的,但是由于赶时间所以修改的很凌乱不适合提PR😂. 总体上移植还是很简单的,只是需要注意一下几点
System.Text.Json和Json.Net的默认序列化行为是不一样的所以需要给System.Text.Json额外指定一个JsonSerializerOptions来确保一致性,类似下面这样:
internal static JsonSerializerOptions JsonOpt = new() { PropertyNameCaseInsensitive = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, IgnoreReadOnlyFields = false, DefaultIgnoreCondition = JsonIgnoreCondition.Never, IncludeFields = true };
在ObjectUtil中需要在序列化时引入这个Option. 不过我没严格的测试具体是那个选项会影响功能实现,只是参考文档把两边的默认行为尽量修改为一致.
基于System.Text.Json的API,我重写了DefaultJsonConfigurationStringParser,以下两个函数由NewBing辅助给出(包括注释😂):
private IDictionary<string, string> ParseString(string input) { var Doc = JsonDocument.Parse(input); SortedDictionary<string, string> SortedDict = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase); var Pairs = this.GetKeyValuePairs(Doc.RootElement, SortedDict); foreach (var Pair in Pairs) { SortedDict.Add(Pair.Key, Pair.Value); } return SortedDict; }
private IEnumerable<KeyValuePair<string, string>> GetKeyValuePairs(JsonElement element, SortedDictionary<string, string> SortedDict, string path = "") { // 如果元素是对象,则遍历其属性 if (element.ValueKind == JsonValueKind.Object) { foreach (var property in element.EnumerateObject()) { // 拼接属性名称到路径 string subPath = path + "/" + property.Name; // 递归调用 foreach (var pair in GetKeyValuePairs(property.Value, SortedDict, subPath)) { yield return pair; } } } // 如果元素是数组,则遍历其元素 else if (element.ValueKind == JsonValueKind.Array) { int index = 0; foreach (var item in element.EnumerateArray()) { // 拼接索引到路径 string subPath = path + ":" + index; // 递归调用 foreach (var pair in GetKeyValuePairs(item, SortedDict, subPath)) { yield return pair; } index++; } } // 否则,元素是一个基本值,直接返回键值对 else { var Pair = new KeyValuePair<string, string>(path.TrimStart('/'), element.ToString()); yield return Pair; } }
- grpc-dotnet不支持以
new List<Grpc.Core.ChannelOption>
的形式传入自定义ChannelOption(本身在grpc定义中ChannelOption也只能在可选值内选择),此外语法和远程地址的格式也有调整所以grpc初始化Channel修改为一下语句:Channel = GrpcChannel.ForAddress($"http://{serverInfo.ServerIp}:{port}", new GrpcChannelOptions { Credentials = ChannelCredentials.Insecure});
除了上述几点以外都是非常常规的改动了,替换Attribute之类的.
目前有支持 grpc-tool 改良后的代码吗?我现在 mac 跑不起来
最新预览版已经完成了相关的迁移。 1.3.9-alpha20240920152555
已发布正式的 1.3.9 版本
如题 现使用的Newtonsoft.Json和Grpc.Core都比较老旧且性能较差,Grpc.Core包本身也处于仅维护状态. 基于性能和面向未来的考量,应该迁移到更新的System.Text.Json和grpc-dotnet 而且这样对于较新的程序来说也不用额外引用大量陈旧的Nuget包