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
Author by
SiriSch
Updated on June 05, 2022Comments
-
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...