zoukankan      html  css  js  c++  java
  • asp.net core 3.1中对Mongodb BsonDocument的序列化和反序列化支持

    最近项目使用了Mongodb作为非结构化数据的存储,大量使用了BsonDocument做为传输对象,但是面临一个问题,直接把BsonDocument通过web api返回前端时候,并不能序列化为期望的json;同样把json传输到后台也不能自动把json组装成BsonDocument

    为此实现了一个自定义的asp.net core 3.1的JsonConverter来处理BsonDocument的序列化和反序列化。
    首先定义一个BsonDocument的转换对象,并且实现JsonConverter<T>

    public class BsonDocumentJsonConverter : JsonConverter<BsonDocument>
    {
        /// <summary>
        /// 反序列化支持
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="typeToConvert"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public override BsonDocument Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            using (var jsonDoc = JsonDocument.ParseValue(ref reader))
            {
                using (var stream = new MemoryStream())
                {
                    using (Utf8JsonWriter writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }))
                    {
                        jsonDoc.WriteTo(writer);
                        writer.Flush();
                        string json = Encoding.UTF8.GetString(stream.ToArray());
                        return BsonDocument.Parse(json);
                    }
                }
            }
        }
        /// <summary>
        /// 序列化支持
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <param name="options"></param>
        public override void Write(Utf8JsonWriter writer, BsonDocument value, JsonSerializerOptions options)
        {
            if (value == null)
            {
                writer.WriteStringValue(String.Empty);
            }
            else
            {
                WirteJson(writer, value);
            }
        }
        private void WirteJson(Utf8JsonWriter writer, BsonDocument bson)
        {
            writer.WriteStartObject();
            var elements = bson.Elements;
            foreach (var item in elements)
            {
                WirteProperty(writer, item.Value, item.Name);
            }
            writer.WriteEndObject();
        }
        private void WirteProperty(Utf8JsonWriter writer, BsonValue bsonValue, string propertyName=null)
        {
            BsonType bsonType = bsonValue.BsonType;
            switch (bsonType)
            {
                case BsonType.EndOfDocument:
                    break;
                case BsonType.Int32:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        writer.WriteNumberValue(bsonValue.AsInt32);
                    }
                    else
                    {
                        writer.WriteNumber(propertyName, bsonValue.AsInt32);
                    }
                    break;
                case BsonType.Int64:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        writer.WriteNumberValue(bsonValue.AsInt64);
                    }
                    else
                    {
                        writer.WriteNumber(propertyName, bsonValue.AsInt64);
                    }
                    break;
                case BsonType.Double:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        writer.WriteNumberValue(bsonValue.AsDouble);
                    }
                    else
                    {
                        writer.WriteNumber(propertyName, bsonValue.AsDouble);
                    }
                    break;
                case BsonType.String:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        writer.WriteStringValue(bsonValue.AsString);
                    }
                    else
                    {
                        writer.WriteString(propertyName, bsonValue.AsString);
                    }
                    break;
                case BsonType.Document:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        WirteJson(writer, bsonValue.AsBsonDocument);
                    }
                    else
                    {
                        writer.WritePropertyName(propertyName);
                        WirteJson(writer, bsonValue.AsBsonDocument);
                    }
                    break;
                case BsonType.Array:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        var bsonArr = bsonValue.AsBsonArray;
                        writer.WriteStartArray();
                        foreach (var abson in bsonArr)
                        {
                            WirteProperty(writer, abson);
                        }
                        writer.WriteEndArray();
                    }
                    else
                    {
                        var bsonArr = bsonValue.AsBsonArray;
                        writer.WritePropertyName(propertyName);
                        writer.WriteStartArray();
                        foreach (var abson in bsonArr)
                        {
                            WirteProperty(writer, abson);
                        }
                        writer.WriteEndArray();
                    }
                    break;
                case BsonType.Boolean:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        writer.WriteBooleanValue(bsonValue.AsBoolean);
                    }
                    else
                    {
                        writer.WriteBoolean(propertyName, bsonValue.AsBoolean);
                    }
                    break;
                case BsonType.DateTime:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        writer.WriteStringValue(bsonValue.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:sszzz"));
                    }
                    else
                    {
                        writer.WriteString(propertyName, bsonValue.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:sszzz"));
                    }
                    break;
                case BsonType.Null:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        writer.WriteNullValue();
                    }
                    else
                    {
                        writer.WriteNull(propertyName);
                    }
                    break;
                case BsonType.ObjectId:
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        writer.WriteStringValue(bsonValue.AsObjectId.ToString());
                    }
                    else
                    {
                        writer.WriteString(propertyName, bsonValue.AsObjectId.ToString());
                    }
                    break;
                case BsonType.RegularExpression:
                    break;
                case BsonType.JavaScript:
                    break;
                case BsonType.Symbol:
                    break;
                case BsonType.JavaScriptWithScope:
                    break;
                case BsonType.Decimal128:
                    break;
                case BsonType.MinKey:
                    break;
                case BsonType.MaxKey:
                    break;
                case BsonType.Timestamp:
                    break;
                case BsonType.Binary:
                    break;
                case BsonType.Undefined:
                    break;
                default:
                    break;
            }
        }
    }
    

    最后在Startup.cs文件中注册该转换器就好了

    public void ConfigureServices(IServiceCollection services)
    {
        //...
        services.AddControllersWithViews().AddJsonOptions(option => {
            //....
            option.JsonSerializerOptions.Converters.Add(new BsonDocumentJsonConverter());
        });
    }
    
  • 相关阅读:
    深入理解java虚拟机笔记Chapter12
    深入理解java虚拟机笔记Chapter11
    深入理解java虚拟机笔记Chapter8
    深入理解java虚拟机笔记Chapter7
    深入理解java虚拟机笔记补充-JVM常见参数设置
    深入理解java虚拟机笔记Chapter4
    深入理解java虚拟机笔记Chapter3-内存分配策略
    Java从Txt文本进行数据提取
    C语言-格式输入输出中“%d,%o,%x,%e,%f,%s,%p”
    嵌入式学习书籍
  • 原文地址:https://www.cnblogs.com/yyzq/p/13626703.html
Copyright © 2011-2022 走看看