草庐IT

c# - 反序列化 BSON ReadBsonType 只能在 State 为 Type 时调用

coder 2023-05-05 原文

我有以下代码:

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 只能在 State 为 Type 时调用,不能在 State 为 Value 时调用

排队:

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

我想反序列化我的对象,它们看起来像这样:

{ 
    "_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;


    }
}

如何防止这个错误?我只想反序列化我的对象...

最佳答案

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

应该是

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

如果状态是类型,将导致检查类型。如果不是类型,则通过,不检查类型

关于c# - 反序列化 BSON ReadBsonType 只能在 State 为 Type 时调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40692346/

有关c# - 反序列化 BSON ReadBsonType 只能在 State 为 Type 时调用的更多相关文章

  1. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  4. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  5. ruby-on-rails - Puma .state 文件 - 2

    我正在尝试使用Capistrano部署带有puma的Rails应用程序。在部署结束时它尝试运行bundleexecpumactl-S/home/deployer/production/shared/sockets/puma.state重启失败了/undefinedmethod`has_key?'forfalse:FalseClass.我只是为puma.state创建了一个空文件。我的问题是这个文件到底是什么,里面应该有什么? 最佳答案 Puma有一个状态文件,记录了进程的PID。如果你是第一次部署,你应该删除.state文件,然后做

  6. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  7. ruby-on-rails - Rails 单表继承 : How to override the value written to the type field - 2

    在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型

  8. ruby-on-rails - carrierwave:在序列化动态属性上安装 uploader - 2

    首先,我使用的是rails3.1.3和来自master的carrierwavegithub仓库的分支。我使用after_init钩子(Hook)来确定基于属性的字段页面模型实例并为这些字段定义属性访问器将值存储在序列化哈希中(希望它清楚我是什么谈论)。这是我正在做的事情的精简版:classPage省略mount_uploader命令让我可以访问我想要的属性。但是当我安装uploader时出现错误消息说“nil类的未定义新方法”我在源代码中读到有方法read_uploader和扩展模块中的write_uploader。我如何必须覆盖这些来制作mount_uploader命令使用我的“虚拟

  9. ruby - Formtastic,拥有 :as input type - 2

    如何将自己的字段类型添加到formtastic中?例如,我需要一个自定义的日期时间输入,我想要这样的东西::my_date%>这显然是行不通的,因为formtastic不知道:my_date(只有:boolean、:string、:datetime等等...)但是我怎样才能添加额外的输入类型呢? 最佳答案 您需要添加自定义输入法:classMyCustomFormtasticFormBuilder这非常适合新的HTML5输入类型。你可以这样使用它:MyCustomFormtasticFormBuilderdo|f|%>:my_dat

  10. c# - C# 中的 Flatten Ruby 方法 - 2

    我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume

随机推荐