question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

EasyNetQ Json.NET JObject serialization - surprising behavior

See original GitHub issue

I’m seeing somewhat weird behavior when trying to send Json.Net JObjects through EasyNetQ’s Default Serializer.

Here’s a contrived example:

using EasyNetQ;
using Newtonsoft.Json.Linq;

namespace TestEasyNetQSerializationBug
{
    class Program
    {
        static void Main(string[] args)
        {
            var obj = JObject.Parse(@"{""data"":""data""}");
            using (var bus = RabbitHutch.CreateBus("amqp://localhost"))
            {
                bus.Publish(obj);
            }
        }
    }
}

The object that gets published is:

{"data":{"$type":"Newtonsoft.Json.Linq.JValue, Newtonsoft.Json","$values":[]}}

Which leaves me sort of 😞

So I saw this issue: https://github.com/EasyNetQ/EasyNetQ/issues/237

Where it was suggested to a user to reimplement the json serializer. So I did that:

static void Main(string[] args)
        {
            var obj = JObject.Parse(@"{""data"":""data""}");
            using (var bus = RabbitHutch.CreateBus("amqp://localhost", serviceRegister => serviceRegister.Register<ISerializer>(
                    serviceProvider => new MyJsonSerializer(new TypeNameSerializer()))
                ))
            {
                bus.Publish(obj);
            }
        }

        public class MyJsonSerializer : ISerializer
        {
            private readonly ITypeNameSerializer typeNameSerializer;
            private readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Auto
            };
            public MyJsonSerializer(ITypeNameSerializer typeNameSerializer)
            {
                this.typeNameSerializer = typeNameSerializer;
            }
            public byte[] MessageToBytes<T>(T message) where T : class
            {
                return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message, serializerSettings));
            }
            public T BytesToMessage<T>(byte[] bytes)
            {
                return JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(bytes), serializerSettings);
            }
            public object BytesToMessage(string typeName, byte[] bytes)
            {
                var type = typeNameSerializer.DeSerialize(typeName);
                return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bytes), type, serializerSettings);
            }
        }

And out comes:

{"data":"data"}

Which leaves me 😀 .

The thing is that Serializer is basically the EasyNetQ serializer without EasyNetQ dependencies present so it will compile properly.

I’m happy to have a solution, but it just seems like weird behavior that it’s behaving this way with what seems like identical code.

For reference: Using Visual Studio 2013, Rabbit MQ 3.4.1 locally installed on Windows Code snippets tested with: EasyNetQ 0.50.1.392, Json.NET 7.0.1

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
mikehadlowcommented, Jun 25, 2015

Don’t forget that EasyNetQ serializes .NET types as JSON to send them over the wire, then de-serializes them at the other end. Here you start with JSON, so it seems redundant to do any serialization at all. Why don’t you use the Advanced API https://github.com/EasyNetQ/EasyNetQ/wiki/The-Advanced-API : Something like:

var properties = new MessageProperties(); var body = Encoding.UTF8.GetBytes(“{ "data": "data" }”); advancedBus.Publish(Exchange.GetDefault, queueName, properties, body);

On Wed, Jun 24, 2015 at 9:13 PM, Todd Ogin notifications@github.com wrote:

I’m seeing somewhat weird behavior when trying to send Json.Net JObjects through EasyNetQ’s Default Serializer.

Here’s a contrived example:

using EasyNetQ; using Newtonsoft.Json.Linq;

namespace TestEasyNetQSerializationBug { class Program { static void Main(string[] args) { var obj = JObject.Parse(@“{”“data”“:”“data”“}”); using (var bus = RabbitHutch.CreateBus(“amqp://localhost”)) { bus.Publish(obj); } } } }

The object that gets published is:

{“data”:{“$type”:“Newtonsoft.Json.Linq.JValue, Newtonsoft.Json”,“$values”:[]}}

Which leaves me sort of [image: 😞]

So I saw this issue: #237 https://github.com/EasyNetQ/EasyNetQ/issues/237

Where it was suggested to a user to reimplement the json serializer. So I did that:

static void Main(string[] args) { var obj = JObject.Parse(@“{”“data”“:”“data”“}”); using (var bus = RabbitHutch.CreateBus(“amqp://localhost”, serviceRegister => serviceRegister.Register<ISerializer>( serviceProvider => new MyJsonSerializer(new TypeNameSerializer())) )) { bus.Publish(obj); } }

    public class MyJsonSerializer : ISerializer
    {
        private readonly ITypeNameSerializer typeNameSerializer;
        private readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Auto
        };
        public MyJsonSerializer(ITypeNameSerializer typeNameSerializer)
        {
            this.typeNameSerializer = typeNameSerializer;
        }
        public byte[] MessageToBytes<T>(T message) where T : class
        {
            return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message, serializerSettings));
        }
        public T BytesToMessage<T>(byte[] bytes)
        {
            return JsonConvert.DeserializeObject<T>(Encoding.UTF8.GetString(bytes), serializerSettings);
        }
        public object BytesToMessage(string typeName, byte[] bytes)
        {
            var type = typeNameSerializer.DeSerialize(typeName);
            return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(bytes), type, serializerSettings);
        }
    }

And out comes:

{“data”:“data”}

Which leaves me [image: 😀] .

The thing is that Serializer is basically the EasyNetQ serializer https://github.com/EasyNetQ/EasyNetQ/blob/master/Source/EasyNetQ/JsonSerializer.cs without EasyNetQ dependencies present so it will compile properly.

I’m happy to have a solution, but it just seems like weird behavior that it’s behaving this way with what seems like identical code.

For reference: Using Visual Studio 2013, Rabbit MQ 3.4.1 locally installed on Windows Code snippets tested with: EasyNetQ 0.50.1.392, Json.NET 7.0.1

— Reply to this email directly or view it on GitHub https://github.com/EasyNetQ/EasyNetQ/issues/460.

0reactions
jhorbulykcommented, Jun 25, 2015

I suppose one of the reasons why one would want EasyNetQ to serialize JObjects as one would expect is in the use case where one wants to mix structured and unstructured data on the message that gets passed to the bus. In @ojintoad’s original example, imagine that instead of obj being a JObject it is a class of the following form:

public class SampleObject{
  public int structuredData1;
  public string structuredData2;
  public DateTime structuredData3;
  public JObject unstructuredData;
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - EastNetQ Json Serialization Exception
Internally EasyNetQ uses the Newtonsoft.JSON serializer. It expects message types to be simple DTOs with default constuctors (i.e. no ...
Read more >
Survaillence of subscription
EasyNetQ will re-subscribe after a network connection is lost, or if the RabbitMQ server bounces. I hadn't considered the case for when a...
Read more >
json serialisation / Binary Serialisation / Best way forward ??
1. Inject your own serializer. · 2. Use the Advanced bus' binary publish/consume API and do your own serialization out of bounds: https://github....
Read more >
You're using HttpClient wrong and it is destabilizing your ...
Once the using block is complete then the disposable object, in this case HttpClient , goes out of scope and is disposed.
Read more >
Code rant - RSSing.com
EasyNetQ is a collection of components that provide services on top of the RabbitMQ.Client library. These do things like serialization, error handling, thread ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found