Deserializing BSON ReadBsonType can only be called when State is Type

10,604
while (context.Reader.ReadBsonType() != BsonType.EndOfDocument)

should be

while (context.Reader.State != BsonReaderState.Type || context.Reader.ReadBsonType() != BsonType.EndOfDocument)

Would cause to check the type if the state is a type. If it is not a type, you will pass and not check the type

Share:
10,604
SiriSch
Author by

SiriSch

Updated on June 05, 2022

Comments

  • SiriSch
    SiriSch almost 2 years

    I have the following Code:

    using MongoDB.Bson;
    using MongoDB.Bson.IO;
    using MongoDB.Bson.Serialization.Attributes;
    using MongoDB.Bson.Serialization.Serializers;
    using MongoDB.Driver;
    using MongoDBTest;
    using ServiceStack;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    namespace protocol.server.API.Clients
    {
        public class ClientService : ServiceStack.Service
        {
            class CylinderSerializer : SerializerBase<Cylinder>
            {
                public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, Cylinder value)
                {
                    var wr = context.Writer;
    
                    wr.WriteStartDocument();
                    wr.WriteName("_id");
                    wr.WriteObjectId(ObjectId.GenerateNewId());
    
    
                  wr.WriteName("description");
                    wr.WriteString(value.description.type);
    
                    context.Writer.WriteEndDocument();
                }
    
    
            public override Cylinder Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
            {
                context.Reader.ReadStartDocument();
                Cylinder a = new Cylinder();
                a.Id = context.Reader.ReadObjectId();
    
    
    
    
                while (context.Reader.State != BsonReaderState.Type && context.Reader.ReadBsonType() != BsonType.EndOfDocument)
                { 
                    a.description.type = context.Reader.ReadString();
                    a.description.kind = context.Reader.ReadString();
                    a.description.year = (short)context.Reader.ReadInt32();
                    a.description.producer = context.Reader.ReadString();
                }
                return a;
            }
    
    
    
            public async Task<List<Cylinder>> Get(GetObjects request)
            {
                MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(typeof(Cylinder), new CylinderSerializer());
                IMongoCollection<Cylinder> collection = Connect._database.GetCollection<Cylinder>("Cylinders");
                var results = await collection.Find(_ => true).ToListAsync();
    
                return results;
            }
        }
    }
    

    and get the error:

    ReadBsonType can only be called when State is Type, not when State is Value

    in line:

     while (context.Reader.ReadBsonType() != BsonType.EndOfDocument)
    

    I want to deserialize my objects, they look like this:

    { 
        "_id" : ObjectId("5826010eb831ee1c70df5f16"), 
        "description" : {
            "type" : "Cylinder", 
            "kind" : "rgdgg", 
            "year" : NumberInt(1997), 
            "producer" : "hnnghng", 
            "brands" : [
                "trhr"
            ], 
            "model" : [
                "Baws"
            ], 
            "internalproducerdesignation" : "tw6", 
            "origin" : "Greece"
        }, 
        "elements" : {
            "nonspringelements" : NumberInt(0), 
            "springelements" : NumberInt(11), 
            "discelements" : NumberInt(0), 
            "magneticelements" : NumberInt(0), 
            "activeelements" : NumberInt(11), 
            "passiveelements" : NumberInt(0), 
            "totalelements" : NumberInt(11)
        }, 
        "profiles" : [
            "d1", 
            "d11"
        ], 
        "certifications" : [
            "", 
            ""
        ], 
        "colors" : [
            "brown", 
            "chrome"
        ], 
        "specialfittings" : [
            "gf", 
            "hrthr", 
            "hgnn", 
            "ngnn", 
            "hngngn", 
            "nghnnn"
        ], 
        "cutdepths" : NumberInt(7), 
        "rareness" : "rare", 
        "value" : {
            "new" : "0", 
            "used" : "$50"
        }, 
        "Blaw" : {
            "tgtgt" : 10.0, 
            "hzhz" : true
        }, 
        "availableat" : "gtgtgtgt", 
        "specialabout" : "jujujuju", 
        "development" : {
            "predecessor" : "", 
            "follower" : "rfrfr"
        }, 
        "media" : [
    
        ]
    }
    

    My Clinder.cs :

    using MongoDB.Bson;
    using MongoDB.Bson.IO;
    using MongoDB.Bson.Serialization.Attributes;
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using MongoDB.Bson.Serialization;
    using MongoDB.Bson.Serialization.Serializers;
    
    namespace protocol.server.API.Clients
    {
    
        public class Cylinder
        {
            [BsonSerializer(typeof(ProductAttributeSerializer))]
            public class ProductAttributeSerializer : IBsonSerializer, IBsonArraySerializer
            {
                public Type ValueType { get { return typeof(List<string>); } }
    
                public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
                {
                    var type = context.Reader.GetCurrentBsonType();
                    List<String> items = new List<String>();
    
                    switch (type)
                    {
                        case BsonType.Document:
    
    
                        case BsonType.Array:
    
                            context.Reader.ReadStartArray();
    
                            while (context.Reader.ReadBsonType() != BsonType.EndOfDocument)
                            {
                                items.Add(context.Reader.ReadString());
                            }
                            context.Reader.ReadEndArray();
                            return new mode(items);
    
                        default:
                            throw new NotImplementedException($"No implementation to deserialize {type}");
                    }
                }
    
                public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
                {
    
                    var d = value;
                    var attributes = value as List<string>;
    
                    if (attributes != null)
                    {
                        context.Writer.WriteStartArray();
    
                        foreach (string attr in attributes)
                        {
                            context.Writer.WriteString(attr);
                        }
    
                        context.Writer.WriteEndArray();
                    }
                }
    
                public bool TryGetItemSerializationInfo(out BsonSerializationInfo serializationInfo)
                {
                    string elementName = null;
                    var serializer = BsonSerializer.LookupSerializer(typeof(string));
                    var nominalType = typeof(string);
                    serializationInfo = new BsonSerializationInfo(elementName, serializer, nominalType);
                    return true;
                }
            }
    
    
            [BsonId]
            public ObjectId Id { get; set; }
    
            [BsonSerializer(typeof(ProductAttributeSerializer))]
            public class mode
            {
                public mode(List<String> pItems)
                {
                    this.items = new List<String>();
                    this.items.Clear();
                    this.items.AddRange(pItems);
                }
                public List<String> items { get; set; }
            }
    
    
            public class des
            {
                public string type { get; set; }
                public string kind { get; set; }
                public short year { get; set; }
                public string producer { get; set; }
    
                public List<string> brands { get; set; }
    
                public string internalproducerdesignation { get; set; }
                public string origin { get; set; }
    
                public mode model { get; set; }
            }
            public class elem
            {
                public short nonspringelements { get; set; }
                public short springelements { get; set; }
                public short discelements { get; set; }
                public short magneticelements { get; set; }
                public short activeelements { get; set; }
                public short passiveelements { get; set; }
                public short totalelements { get; set; }
            }
            public des description = new des();
            public elem elements = new elem();
    
            public IEnumerable<string> profiles { get; set; }
            public IEnumerable<string> certifications { get; set; }
            public IEnumerable<string> colors { get; set; }
            public IEnumerable<string> specialfittings { get; set; }
            public short cutdepths { get; set; }
            public string rareness { get; set; }
    
            public class val
            {
                public String @new { get; set; }
                public String used { get; set; }
            }
            public val value = new val();
    
            public class Pi
            {
                public Double difficulty { get; set; }
                public bool alreadypicked { get; set; }
            }
            public Pi Picking = new Pi();
            public string availableat { get; set; }
            public string specialabout { get; set; }
    
            public class devel
            {
                public string predecessor { get; set; }
                public string follower { get; set; }
            }
    
            public devel development = new devel();
    
            public Object[] media;
    
    
        }
    }
    

    How to prevent this error ? I just want to deserialize my objects...