Litedb: InvalidCastException for DeserializeDictionary when Key is of type Guid

Created on 23 Mar 2017  路  9Comments  路  Source: mbdavid/LiteDB

Stack trace :

System.InvalidCastException: Invalid cast from 'System.String' to 'System.Guid'.
   at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
   at LiteDB.BsonMapper.DeserializeDictionary(Type K, Type T, IDictionary dict, BsonDocument value)
   at LiteDB.BsonMapper.Deserialize(Type type, BsonValue value)
   at LiteDB.BsonMapper.DeserializeObject(Type type, Object obj, BsonDocument value)
   at LiteDB.BsonMapper.Deserialize(Type type, BsonValue value)
   at LiteDB.BsonMapper.ToObject[T](BsonDocument doc)
   at LiteDB.LiteCollection`1.<Find>d__17.MoveNext()

Data Type :

    public class QuizData
    {
        public QuizData()
        { }
        public string RollNumber { get; set; }
        public Dictionary<Guid,Choice> QuestionChoiceList { get; set; }
    }

Method Call :

_db.GetCollection<QuizData>("collectionName").FindAll();

I think it's throwing because Generic conversion doesn't support GUIDs.
Platform : ASP.NET Core 1.1.0 on .NET Core 1.1.0 using .NET Core SDK 1.0.0-preview2-1-003177
Edit : I got it working by forking and using a very quick-and-dirty fix in DeserializeDictionary()

Guid temp;
var k = Guid.TryParse(key, out temp) ? 
temp : K.GetTypeInfo().IsEnum ? 
Enum.Parse(K, key) : Convert.ChangeType(key, K);

So basically right now you can't have Guid as a TKey in an IDictionary

question

All 9 comments

Hi @prajaybasu, it's not possible use Dictionary with non string TKey because each key must be a valid key in JSON (and must be a string). You can change your Dictionary to a List or you can implement your custom serialization to this Dictionary instance, using BsonMapper.Global.RegisterType<...>(...)

I suppose it does convert other TKey like int to string ?
Guid does have ToString(), it's just that Convert.ChangeType doesn't support it, I think it needs a special case.
Other deserializers like Newtonsoft support Guid out of the box though - the model works fine with Newtonsoft on the client side, I had to fork to add the special case for Guid in DeserializeDictionary() on the server side and it just works fine for me currently. (SortedDictionary also works fine)

Agree with @prajaybasu here, if some simple modification could expand the usability that would be worth it.

http://stackoverflow.com/questions/393731/generic-conversion-function-doesnt-seem-to-work-with-guids

I've got the same issue... When is this fixed?

Might be better to rename this issue to something like "InvalidCastException for DeserializeDictionary when Key is of non primitive or string type"
Since it affects any non string/primitive key for a dictionary

as a side note, you could just serialize the key
https://github.com/mbdavid/LiteDB/blob/0412d11ed9492bd0e442db3e18b195b164bf5ca9/LiteDB/Client/Mapper/BsonMapper.Serialize.cs#L167
with something such as
o[this.Serialize(key.GetType(), key).ToString()] = this.Serialize(type, value, depth);

and then handle the deserialization of keys somehow here
https://github.com/mbdavid/LiteDB/blob/f568f133077dc24d2b74fb7b23f1bf64e042706d/LiteDB/Client/Mapper/BsonMapper.Deserialize.cs#L252
I haven't really found a way to deserialize the key from string back into it's class however.

Using Json.NET for this in particular does allow this to work though.
var k = K.IsEnum ? Enum.Parse(K, el.Key) : JsonConvert.DeserializeObject(el.Key, K);
that on it's own doesn't support Guids due to how LiteDB serializes them. But since this part uses Json.NET you could also serialize the keys using Json.NET
o[JsonConvert.SerializeObject(key)] = this.Serialize(type, value, depth);
Which then serializes fine from all my testing.

Hi! With the objective of organizing our issues, we are closing old unsolved issues. Please check the latest version of LiteDB and open a new issue if your problem/question/suggestion still applies. Thanks!

@lbnascimento so you are officially abandoning support for v4 now?

Hi @omfgicbf, v4 will be maintained only for bugs and critical updates. Any new feature will be applied only in v5 (it's too hard keep both in evolution)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sandolkakos picture sandolkakos  路  3Comments

lidanger picture lidanger  路  3Comments

darcome picture darcome  路  3Comments

ghiboz picture ghiboz  路  4Comments

nightroman picture nightroman  路  3Comments