2016-11-19 8 views
5

मैं निम्नलिखित कोड है:deserializing BSON ReadBsonType केवल कहा जा सकता है

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

और त्रुटि मिलती है:

ReadBsonType केवल जब राज्य का प्रकार, जब नहीं राज्य है कहा जा सकता है मूल्य

लाइन में

:

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

मैं अपने वस्तुओं deserialize करना चाहते हैं, वे लो ठीक इस तरह:

{ 
    "_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" : [ 

    ] 
} 

मेरे 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; 


    } 
} 

इस त्रुटि को रोकने के लिए कैसे? मैं सिर्फ अपनी वस्तुओं deserialize करना चाहते हैं ...

उत्तर

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

होना चाहिए

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

प्रकार की जांच के लिए अगर राज्य एक प्रकार है कारण होगा। यदि यह एक प्रकार नहीं है, तो आप

+0

इससे कोई मदद नहीं मिली। मैंने अपना कोड संपादित किया। – SiriSch

0

को यह सुनिश्चित नहीं करेंगे कि अगर आप केवल एक ऑब्जेक्ट (विवरण) के गुणों को भरना चाहते हैं तो लूप के दौरान उपयोग क्यों करें। आप इसे इस तरह कर सकते हैं:

public override Cylinder Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { 
    context.Reader.ReadStartDocument(); 
    Cylinder a = new Cylinder(); 
    a.Id = context.Reader.ReadObjectId(); 
    context.Reader.ReadStartDocument(); 
    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; 
} 

टेस्ट (फ़ाइल bson.txt अपने प्रश्न से शब्दशः नकल की जाती है):

static void Main(string[] args) { 
    var cylinder = new CylinderSerializer().Deserialize(BsonDeserializationContext.CreateRoot(new BsonDocumentReader(BsonDocument.Parse(File.ReadAllText(@"G:\tmp\bson.txt"))))); 
    Console.ReadKey(); 
} 
+0

अरे और धन्यवाद। आपकी पहली पंक्ति (ReadStartDocument) एक त्रुटि में चलाती है: ReadStartDocument केवल तभी कॉल किया जा सकता है जब CurrentBsonType दस्तावेज़ है, न कि जब CurrentBsonType ऐरे है। मैं इसे समझ नहीं पा रहा हूं, क्योंकि मैंने सोचा था कि करने के लिए पहली बात है ReadStartDocument ... और उसके बाद। ReadObjectId() और फिर। ReadName()। एक और बात जो मैं समझ नहीं पा रहा हूं वह है कि आप रीडस्टार्ट दस्तावेज़ का दो बार क्यों उपयोग करते हैं और आप इसका उपयोग क्यों नहीं करते हैं। ReadEndDocument() .. – SiriSch

+0

मैंने यह दिखाने के लिए उत्तर अपडेट किया कि मैंने आपके द्वारा प्रदान किए गए डेटा का उपयोग करके इसका परीक्षण कैसे किया। ReadStartDocument के लिए - मैं इसे दूसरी बार कॉल करता हूं क्योंकि "_id" के ठीक बाद आपके पास एक और दस्तावेज़ (जटिल वस्तु) - "विवरण" है। – Evk

+0

अरे। धन्यवाद, लेकिन यह मेरी मदद नहीं करता है .. जैसा कि आप देख सकते हैं कि मैं सर्विसस्टैक का उपयोग कर रहा हूं और मुझे नहीं पता कि क्यों, लेकिन जिस समस्या का सामना मैं कर रहा हूं वह स्थानीय फाइल के साथ आपके परीक्षण से अलग दिखता है। मैंने आपकी स्थानीय फ़ाइल deserialization का परीक्षण किया है और यह मेरे लिए काम करता है, लेकिन मेरे द्वारा उपयोग किए जा रहे दस्तावेज़ों को एक मोंगोडीबी द्वारा पुनर्प्राप्त किया जाता है। मैं कुछ कोड जोड़ने जा रहा हूं। त्रुटि: ReadStartDocument केवल तभी कॉल किया जा सकता है जब CurrentBsonType दस्तावेज़ है, न कि जब CurrentBsonType ऐरे है। – SiriSch

0

यह काम का एक बहुत कुछ खुद serializer इस तरह से लिखने के लिए है। इस तरह मैंने सिलेंडर के लिए किया था। मैं इस तरह से अपने नमूना deserialize करने में कामयाब रहे।

कृपया उल्लेख करें कि स्ट्रिंग सरणी को deserialize करने के लिए वहाँ एक सरल मदद विधि है। आपके पास "ब्लॉ" डेटा के लिए कोई कक्षा नहीं है, इसलिए मैंने इसे उपयोग किए गए चर में नहीं पढ़ा।

public override Cylinder Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) 
    { 
     context.Reader.ReadStartDocument(); 
     Cylinder a = new Cylinder {Id = context.Reader.ReadObjectId()}; 

     context.Reader.ReadStartDocument(); 

     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(); 

     context.Reader.ReadStartArray(); 
     a.description.brands = new List<string>(); 
     while (context.Reader.ReadBsonType() != BsonType.EndOfDocument) 
     { 
      a.description.brands.Add(context.Reader.ReadString()); 
     } 
     context.Reader.ReadEndArray(); 

     context.Reader.ReadStartArray(); 
     a.description.model = new Cylinder.mode(new List<string>()); 
     while (context.Reader.ReadBsonType() != BsonType.EndOfDocument) 
     { 
      a.description.model.items.Add(context.Reader.ReadString()); 
     } 
     context.Reader.ReadEndArray(); 

     a.description.internalproducerdesignation = context.Reader.ReadString(); 
     a.description.origin = context.Reader.ReadString(); 

     context.Reader.ReadEndDocument(); 
     context.Reader.ReadStartDocument(); 

     a.elements = new Cylinder.elem 
     { 
      nonspringelements = (short) context.Reader.ReadInt32(), 
      springelements = (short) context.Reader.ReadInt32(), 
      discelements = (short) context.Reader.ReadInt32(), 
      magneticelements = (short) context.Reader.ReadInt32(), 
      activeelements = (short) context.Reader.ReadInt32(), 
      passiveelements = (short) context.Reader.ReadInt32(), 
      totalelements = (short) context.Reader.ReadInt32() 
     }; 

     context.Reader.ReadEndDocument(); 

     a.profiles = readStringArray(context); 
     a.certifications = readStringArray(context); 
     a.colors = readStringArray(context); 
     a.specialfittings = readStringArray(context); 

     a.cutdepths = (short) context.Reader.ReadInt32(); 

     a.rareness = context.Reader.ReadString(); 

     context.Reader.ReadStartDocument(); 
     a.value = new Cylinder.val 
     { 
      @new = context.Reader.ReadString(), 
      used = context.Reader.ReadString() 
     }; 
     context.Reader.ReadEndDocument(); 

     context.Reader.ReadStartDocument(); 
     var blawInt = context.Reader.ReadDouble(); 
     var blawBool = context.Reader.ReadBoolean(); 
     context.Reader.ReadEndDocument(); 

     a.availableat = context.Reader.ReadString(); 
     a.specialabout = context.Reader.ReadString(); 

     context.Reader.ReadStartDocument(); 
     a.development = new Cylinder.devel 
     { 
      predecessor = context.Reader.ReadString(), 
      follower = context.Reader.ReadString() 
     }; 
     context.Reader.ReadEndDocument(); 

     var objects=new List<object>(); 
     context.Reader.ReadStartArray(); 
     while (context.Reader.ReadBsonType() != BsonType.EndOfDocument) 
     { 
      objects.Add(context.Reader.ReadString()); 
     } 
     context.Reader.ReadEndArray(); 
     a.media = objects.ToArray(); 

     context.Reader.ReadEndDocument(); 
     return a; 
    } 

    private static IEnumerable<string> readStringArray(BsonDeserializationContext context) 
    { 
     context.Reader.ReadStartArray(); 
     var strings = new List<string>(); 
     while (context.Reader.ReadBsonType() != BsonType.EndOfDocument) 
     { 
      strings.Add(context.Reader.ReadString()); 
     } 
     context.Reader.ReadEndArray(); 
     return strings; 
    } 
+0

हे और धन्यवाद, मुझे समझ में नहीं आता कि यह त्रुटि क्यों होती है, लेकिन मुझे एक ReadObjectId केवल तभी बुलाया जा सकता है जब CurrentBsonType ऑब्जेक्ट आईडी है, न कि जब CurrentBsonType आपके कोड का उपयोग कर Int32 है ... – SiriSch

+0

क्षमा करें, कोड पूरा नहीं हुआ था, अब यह काम करता है और आपके द्वारा पोस्ट किए गए दस्तावेज़ को सटीक रूप से deserialize कर सकता है, मुझे नहीं पता, आपके संग्रह में एक और दस्तावेज क्या हैं और अभी भी लगता है कि यह आपके डेटा को deserialize करने का सबसे अच्छा तरीका नहीं है। –

संबंधित मुद्दे