EastNetQ json 序列化异常

本文关键字:异常 序列化 json EastNetQ | 更新日期: 2023-09-27 18:36:33

我对消息传递相当陌生,我已经决定使用EasyNetQ(RabbitMQ .Net)构建一个原型。

我已经创建了发布服务器和订阅服务器,一切似乎都运行良好。 我的 Web 服务应用程序中的发布服务器捕获了发送到数据库的所有命令。 我让控制台应用程序中的订阅者接收消息。

但是,当订阅服务器选取 Command 对象时,它会引发错误:

类应该有一个默认构造函数、一个带参数的构造函数或一个用 JsonConstructor 属性标记的构造函数。

在我的原型中,我有一个这样的命令类:

[Serializable]
public class Command
{
    private Type _type;
    private string _method;
    private object[] _params;
    public Command(){
    }
    public Command(Type type, string method, params object[] Params)
    {
        _type       = type;
        _method     = method;
        _params     = Params;
    }
    public Command(Type type, string method, params object[] Params)
    {
        _type           = type;
        _method         = method;
        _params         = Params;
    }
    public Type Type { get { return _type; } }
    public string Method { get { return _method; } }

    public object[] Params { get { return _params; } }
}

我正在将此命令对象传递给发布服务器:

public void Publish(Command message){
        using(var publishChannel = RabbitManager.Instance.OpenPublishChannel()){
            publishChannel.Publish(message);
        }
    }

订阅者选取消息:

public void SubscribeCommand(){
        RabbitManager.Instance.Subscribe<Command>("my_subscription_id", msg => Console.WriteLine(msg.Method));
    }

当我运行它并且命令对象由订阅服务器处理时,我收到错误:

错误:订阅 calback 引发异常。

交换: 'Entities_Command:BL'
路由密钥:"
重新交付:"假"

消息:{"类型":"BL.DataAccess.XXX, BL, 版本=1.2.0.0, 区域性=中性, 公钥令牌=xxx","方法":"GET","参数":[1,true,3]}

基本属性:

内容类型=空, 内容编码=空, 标头=[], 传递模式=2, 优先级=0, 相关性 Id=8aa21f39-4020-4904-b90d-4cb123d3cac0, replyTo=NULL, 过期=空, 消息 ID =空, 时间戳=0,类型=Entities_Command:BL, 用户 ID =空, AppId=空, 群集 ID =空 异常:Newtonsoft.Json.JsonSerialization异常:找不到用于类型Entities.Command的构造函数。类应该有一个默认构造函数、一个带参数的构造函数或一个用 JsonConstructor 属性标记的构造函数。路径"类型",第 1 行,位置 8。 at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultConstructor) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonPropertycontainerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) at EasyNetQ.JsonSerializer.BytesToMessage[T](Byte[] bytes) at EasyNetQ.RabbitAdvancedBus.<>c_DisplayClass5'1.b_4(Byte[] body, MessageProperties properties, MessageReceivedInfo messageRecievedInfo) at EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandler(ConsumerExecution Context context)

我在 Command 类中有一个默认构造函数,但我仍然不确定为什么会发生这种情况。

我尝试只传递一个对象类型(而不是命令),它工作正常。

有人可以解释我在这里做错了什么吗?

EastNetQ json 序列化异常

EasyNetQ 内部使用 Newtonsoft.JSON 序列化程序。它期望消息类型是具有默认构造器(即没有构造函数或没有参数)和读写属性的简单 DTO。消息类型(Command 类)具有只读属性,这就是序列化失败的原因。

序列化程序的另一个限制是它不处理多态类型。如果你期望能够将你的对象[]参数转换为可用的东西,它是行不通的。

命令模式不是 EasyNetQ 当前设计支持的模式,尽管值得考虑使用高级 API 并执行自己的自定义序列化。不过,计划在不久的将来发布一个支持多态命令的版本。