如何在不抛出异常的情况下安全反序列化MessagePack消息?
问题:MessagePack反序列化时避免异常的解决方案
我的DTO定义
public class InvocationMessage { public string MethodName { get; set; } public object?[]? Args { get; set; } }
初始序列化方式
最初我使用 MessagePackSerializer.Serialize(Msg, ContractlessStandardResolver.Options); 对该DTO进行序列化。
自定义格式化器的实现
反序列化时,我需要将Args中的object转换为具体类型,但默认方式无法实现,因此编写了自定义格式化器:
public InvocationMessage Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { var result = new InvocationMessage { MethodName = reader.ReadString() }; // 测试用硬编码 var argTypes = new Type[] { typeof(SomeType) }; if (reader.TryReadArrayHeader(out int count)) { result.Args = new object?[count]; for (int i = 0; i < argTypes.Length; i++) { result.Args[i] = MessagePackSerializer.Deserialize(argTypes[i], ref reader, ContractlessStandardResolver.Options.WithSecurity(MessagePackSecurity.UntrustedData)); } } return result; } public void Serialize(ref MessagePackWriter writer, InvocationMessage value, MessagePackSerializerOptions options) { var methodName = Encoding.UTF8.GetBytes(value.MethodName); writer.WriteString(methodName); if (value.Args is not null && value.Args.Length > 0) { writer.WriteArrayHeader(value.Args.Length); foreach (var arg in value.Args) { MessagePackSerializer.Serialize(ref writer, arg, ContractlessStandardResolver.Options); } } }
遇到的异常问题
反序列化如下示例消息时,频繁抛出异常:
var msg = new InvocationMessage { MethodName = "sometestname", Args = new object?[] { new { Test = 3 }, new { ReceiverId = "12ds", Content = "s", }, new { Test2 = 5 }, } };
异常原因包括:尝试将未知类型反序列化为SomeType、SomeType的ReceiverId属性需要string类型但实际传入int等多种类型不匹配情况。
需求
由于异常会严重影响应用性能,我需要避免抛出异常,但MessagePack没有类似TryDeserialize的方法,寻求可行解决方案。
内容的提问来源于stack exchange,提问作者Szyszka947
相关产品推荐
相关产品推荐

