I have the following model that I'm 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 into a POCO (each occurrence is vastly different).
I don't want to store the person's first and last names since that information is already stored in a SQL database and I don't want to have to worry about syncing changes. So I've decorated those parameters with [BsonIgnore]
. When my app code retrieves the Person
from MongoDB it populates the FirstName
and LastName
parameters before serializing it to JSON, like so:
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);
}
The resulting JSON, however, is missing FirstName
and LastName
nodes, apparently because they were decorated with [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?
I don't think that's possible while you're using the driver itself to serialize your objects into json
.
However you can (and probably should) use json.net
to serialize into json
. That way your BsonIgnore
will have no effect on json
serialization and the json
attributes (like JsonIgnore
) will have no effect on 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 that will also be a better design because the bson
is used for the DB and the json
(mostly) is used for web consumption, and so be done using different tools.
I decided to take I3arnon's advice and use Json.NET. The problem is Json.NET doesn't know how to handle most Mongo types, so serializing the Resume
property was problematic because it's of type BsonDocument
. Here's what I came up with:
Json.NET can normally serialize the result of a Mongo query, however the BsonDocument
gave it a problem. In the case of my example, Json.NET could not serialize Person
without special instructions on how to handle a 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With