【问题标题】:EastNetQ Json Serialization ExceptionEastNetQ Json 序列化异常
【发布时间】:2013-10-22 12:07:16
【问题描述】:

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

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

但是,当订阅者获取 Command 对象时,它会抛出错误:

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

在我的原型中,我有一个像这样的 Command 类:

[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));
    }

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

错误:订阅回调抛出异常。

交换:'Entities_Command:BL'
路由键:''
重新发送:'False'

消息:{"Type":"BL.DataAccess.XXX, BL, Version=1.2.0.0, Culture=neutral, PublicKeyToken=xxx","方法":"GET","Params":[1,true,3]}

基本属性:

ContentType=NULL, ContentEncoding=NULL, Headers=[], DeliveryMode=2, Priority=0, CorrelationId=8aa21f39-4020-4904-b90d-4cb123d3cac0, ReplyTo=NULL, Expiration=NULL, MessageId=NULL, Timestamp=0,Type =Entities_Command:BL, UserId=NULL, AppId=NULL, ClusterId=NULL 异常:Newtonsoft.Json.JsonSerializationException:找不到用于类型 Entities.Command 的构造函数。一个类应该有一个默认构造函数、一个带参数的构造函数或一个标有 JsonConstructor 属性的构造函数。路径“类型”,第 1 行,位置 8。在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject 的 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader 阅读器,JsonObjectContract objectContract,JsonProperty containerMember,JsonProperty containerProperty,String id,Boolean& createdFromNonDefaultConstructor) (JsonReader reader,Type objectType,JsonContract contract,JsonProperty member,JsonContainerContract containerContract,JsonProperty containerMember,Object existingValue)在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](字符串值,JsonSerializerSettings 设置)在 EasyNetQ.JsonSerializer.BytesToMessage[T](Byte[] bytes) 在 EasyNetQ.RabbitAdvancedBus.c_DisplayClass5`1.b_4(Byte[] body, MessageProperties 属性, MessageReceivedInfo messageRecievedInfo) 在 EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandler(ConsumerExecution Context context)

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

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

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

【问题讨论】:

    标签: c# .net rabbitmq easynetq


    【解决方案1】:

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

    序列化程序的另一个限制是它不处理多态类型。如果您希望能够将您的 object[] 参数转换为可用的东西,那么它不会起作用。

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

    【讨论】:

    • 感谢 Mike,我想我可以创建一个简化的类并将我需要的数据传输到它,而不用将 EasyNetQ 传递给厨房水槽。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    • 2014-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 2019-08-22
    相关资源
    最近更新 更多