Ignore property when saving POCO in MongoDB, but do not ignore it when serializing in JSON

I have the following model that I am storing in 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 } 

Resume is a BsonDocument , where I store arbitrary JSON that cannot be standardized in POCO (each event is very different).

I do not want to store the username and surname, since this information is already stored in the SQL database, and I do not want to worry about synchronizing changes. Thus, I have decorated these parameters with [BsonIgnore] . When the application code retrieves Person from MongoDB, it populates the FirstName and LastName parameters before serializing it to JSON, for example:

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

As a result of JSON, however, the FirstName and LastName nodes are missing, apparently because they were decorated with [BsonIgnore] .

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

+6
source share
3 answers

I don't think this is possible when using the driver itself to serialize your objects in json .

However, you can (and probably should) use json.net to serialize in json . This way, your BsonIgnore will not affect json serialization, and json attributes (like JsonIgnore ) will not affect your mongo driver.

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

In my opinion, this will also be a better design, because bson used for the database, and json (mainly) is used for use on the network, and so do the various tools.

+4
source

I decided to take I3arnon advice and use Json.NET. The problem is that Json.NET does not know how to handle most types of Mongo, so serializing the Resume property was problematic because it is a BsonDocument type. Here is what I came up with:

Json.NET can usually serialize the result of a Mongo request, however BsonDocument gave it a problem. In the case of my example, Json.NET was unable to serialize Person without special instructions on how to handle BsonDocument .

First I created a JsonConverter called BsonDocumentConverter:

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

This converter uses the MongoDB C # driver to serialize any BsonDocuments.

To use the converter:

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

Use the [NotMapped] attribute for the firstname and lastname properties and remove the [BsonIgnore] attribute. He will work

-2
source

All Articles