Reputation: 205
I have been working to convert MongoDB BSON documents to List object in c#. While converting, i get below error
"{"Unexpected character encountered while parsing value: O. Path '_id', line 1, position 10."}"
After searching for similar issues in stackoverflow, i found below link
JSON.NET cast error when serializing Mongo ObjectId
and i followed the same.
My Code:
Sample Entity/Model
public class BTMObj
{
[JsonConverter(typeof(MongoDataSerializer))]
public ObjectId _id { get; set; }
public string requestFormat { get; set; }
}
public class MongoDataSerializer : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ObjectId);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.String)
{
throw new Exception(
String.Format("Unexpected token parsing ObjectId. Expected String, got {0}.",
reader.TokenType));
}
var value = (string)reader.Value;
return String.IsNullOrEmpty(value) ? ObjectId.Empty : new ObjectId(value);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is ObjectId)
{
var objectId = (ObjectId)value;
writer.WriteValue(objectId != ObjectId.Empty ? objectId.ToString() : String.Empty);
}
else
{
throw new Exception("Expected ObjectId value.");
}
}
}
public List<T> GetMongoCollection<T>(string collectionName)
{
try
{
List<T> list = new List<T>();
var client = new MongoClient(Convert.ToString(ConfigurationManager.AppSettings["MONGO_CONNECTION"]));
var database = client.GetDatabase(Convert.ToString(ConfigurationManager.AppSettings["MONGO_DB"]));
var collection = database.GetCollection<BsonDocument>(collectionName);
var documents = collection.Find(new BsonDocument()).ToList();
foreach (var document in documents)
{
try
{
list.Add(JsonConvert.DeserializeObject<T>(document.ToJson()));
}
catch (Exception ex)
{
}
}
return list;
}
catch (Exception ex)
{
throw;
}
}
Call to Method
list = mongoDBOperations.GetMongoCollection<BTMObj>(Collection);
MongoDataSerializer class overridden methods should get call which is not the case. Our need is to get ObjectId as string in Model.
Please help in resolving this issue.
Sample document.toJson() value
{
"_id": ObjectId("611cf42e1e4c89336b6fe2f0"),
"requestFormat": "json"
}
Upvotes: 0
Views: 2601
Reputation: 151674
You only used half of the relevant code.
If you write this JSON:
"_id": ObjectId("611cf42e1e4c89336b6fe2f0"),
"requestFormat": "json"
}
As BsonObject.ToJson()
does, then that's not JSON. The ObjectId(...)
dialect, just as Date()
, NumberLong()
, NumberInt()
and NumberDecimal()
are constructs that make MongoDB spit out invalid JSON, because it's a representation of its internal BSON storage format.
So if you want to treat it as JSON, write valid JSON. The code is right there in the link: you need to serialize the object yourself. See How to deserialize a BsonDocument object back to class.
First make sure the Mongo C# driver deserializes the BSON into your POCO:
// Prefer using statically-typed extension methods such as
// _collection.FindAs<MyType>()
var deserialized = BsonSerializer.Deserialize<BTMobj>(document);
Then serialize that object to JSON using your converter:
var json = JsonConvert.SerializeObject(deserialized);
Your output will then become the very parseable:
"_id": "611cf42e1e4c89336b6fe2f0",
"requestFormat": "json"
}
And your type's metadata (attributes) will tell the parser to parse "611cf42e1e4c89336b6fe2f0" as a BsonObjectId
when you try to deserialize it into a BTMobj
again.
Upvotes: 1