首页 文章

在MongoDB中保存POCO时忽略属性,但在序列化为JSON时不忽略它

提问于
浏览
6

我有以下模型,我存储在MongoDB中:

public class Person
{
    public ObjectId Id { get; set; }
    public Int PersonId { get; set; }
    public BsonDocument Resume { get; set; } // arbitrary JSON

    [BsonIgnore]
    public string FirstName { get; set; }    // stored elsewhere, 
                                             // populated at runtime
    [BsonIgnore]
    public string LastName { get; set; }     // ditto
}

ResumeBsonDocument ,其中我存储了无法标准化为POCO的任意JSON(每次出现都大不相同) .

我没有't want to store the person'的姓名和姓,因为该信息已经存储在SQL数据库中,我没有't want to have to worry about syncing changes. So I'用 [BsonIgnore] 装饰这些参数 . 当我的应用程序代码从MongoDB中检索 Person 时,它会在将序列化为JSON之前填充 FirstNameLastName 参数,如下所示:

public ActionResult GetPerson(int id)
{
    var query = New QueryDocument("_id", ObjectId.Parse(id));
    // personCollection is Collection<Person>
    var person = personCollection.FindOne(query);

    var pc = personCache.GetPerson(person.PersonId);

    person.FirstName = pc.FirstName;
    person.LastName = pc.LastName;

    var settings = New JsonWriterSettings() { Outputmode = JsonOutputMode.Strict }
    return Json(person.ToJson(settings), JsonRequestBehavior.AllowGet);
}

但是,生成的JSON缺少 FirstNameLastName 节点,显然是因为它们用 [BsonIgnore] 装饰 .

Is there a way to tell the Official MongoDB C# driver to ignore saving the parameters in MongoDB but not ignore it when serializing into JSON?

3 回答

  • 4

    当您使用驱动程序本身将对象序列化为 json 时,我不可能't think that' .

    However 你可以(也可能应该)使用json.net序列化为 json . 这样你的 BsonIgnorejson 序列化没有影响, json 属性(如 JsonIgnore )对你的mongo驱动没有任何影响 .

    public class Person
    {
        [JsonIgnore]
        publis string FullName {get; set;}
        [BsonIgnore]
        public string FirstName { get; set; }
        [BsonIgnore]
        public string LastName { get; set; }
    }
    

    在我看来,这也是一个更好的设计,因为 bson 用于数据库, json (大多数)用于网络消费,因此可以使用不同的工具完成 .

  • -2

    我决定采用I3arnon的advice并使用Json.NET . 问题是Json.NET不知道如何处理大多数Mongo类型,因此序列化 Resume 属性是有问题的,因为它的类型为 BsonDocument . 这是我想出的:

    Json.NET通常可以序列化Mongo查询的结果,但 BsonDocument 给它一个问题 . 在我的示例中,如果没有关于如何处理 BsonDocument 的特殊说明,Json.NET无法序列化 Person .

    首先,我创建了一个名为BsonDocumentConverter的 JsonConverter

    public class BsonDocumentConverter : JsonConverter
    {
        public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, JsonSerializer serializer)
        {
            var settings = new JsonWriterSettings()
            {
                OutputMode = JsonOutputMode.Strict
            };
    
            writer.WriteRawValue(value.ToJson(settings));
        }
    
        public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException("Why would I want to deserialize?");
        }
    
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(BsonDocument);
        }
    }
    

    此转换器使用MongoDB C#驱动程序序列化任何BsonDocuments .

    要使用转换器:

    var result = JsonConvert.SerializeObject(person, Formatting.None, 
                     new JsonSerializerSettings() { 
                         NullValueHandling = NullValueHandling.Ignore,
                         Converters = new List<JsonConverter>() { 
                             new BsonDocumentConverter() 
                             } 
                     });
    
    return Json(result, JsonRequestBehavior.AllowGet);
    
  • 5

    对firstname和lastname属性使用[NotMapped]属性并删除[BsonIgnore]属性 . 它会工作

相关问题