aspnet / Security

[Archived] Middleware for security and authorization of web apps. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
1.27k stars 600 forks source link

AVRO serialization error - Could not find any matching known type for 'Newtonsoft.Json.Linq.JToken' using c# #1895

Closed ashuthinks closed 5 years ago

ashuthinks commented 5 years ago

I'm using nuget Microsoft.Hadoop.Avro2 for avro serialization.

I'm using below code -

public byte[] ReadAsAvroWithHeader(string messageType,JObject obj)
        {
            Encoding encoding = new System.Text.UTF8Encoding();
            string header = $"{messageType},{Guid.NewGuid().ToString()}";

            byte[] headerBytes = Encoding.UTF8.GetBytes(header);
            byte[] avroBytes = ReadAsAvro(obj).ToArray();

            //Verify data
            string avHeader = encoding.GetString(headerBytes);
            string avAvro = encoding.GetString(avroBytes);

            return avroPayload;
        }

        public virtual MemoryStream ReadAsAvro<T>(T Instance)
        {
            var stream = new MemoryStream();

            using (var avroWriter = AvroContainer.CreateWriter<T>(stream, Codec.Deflate))
            {
                using (var seqWriter = new SequentialWriter<T>(avroWriter, 24))
                {
                    seqWriter.Write(Instance);
                }
            }

            return stream;
        }

i'm passing simple json data into obj data is - {"id": "Demo123","count": 2}

i'm getting exception at this line -

using (var avroWriter = AvroContainer.CreateWriter(stream, Codec.Deflate)) Error- Could not find any matching known type for 'Newtonsoft.Json.Linq.JToken'

I checked like if I create a c# class out of this input json and mark it as DataContract it works as expected .

i did it like below -

  [DataContract(Name = "RootObject", Namespace = "ConsoleApp4")]
    public class RootObject
    {
        [DataMember(Name = "id")]
        public string id{ get; set; }
        [DataMember(Name = "count")]
        public int count{ get; set; }

    }

and execute the method like below its works but i cant create a class as i'm getting json input and it may not have same properties to create a class :( -

RootObject test = JsonConvert.DeserializeObject(obj.ToString()); byte[] avroBytes = ReadAsAvro(test).ToArray();

any work around to use json message as it is like "obj.ToString()" ?

Tratcher commented 5 years ago

I expect you're having a version conflict with Newtonsoft.Json. Microsoft.Hadoop.Avro2 uses 9.0.1 but ASP.NET Core uses 11.0.2.

You'll want to find the owners of Microsoft.Hadoop.Avro2, it's unclear if that package will work with later versions of Newtonsoft.Json.

ashuthinks commented 5 years ago

i have tried using other version nuget also now i do not get any error but when I pass Jobject it is not creating message properly :( like when i use RootObject I can verify data using this statement. string avAvro = encoding.GetString(avroBytes);

muratg commented 5 years ago

Please file your issue here: https://github.com/Azure/azure-sdk-for-net/tree/master/src/ServiceManagement/HDInsight/Microsoft.Hadoop.Avro

This is not related to ASP.NET.