Cosmos DB Newtonsoft反序列化问题 [英] Cosmos DB Newtonsoft Deserialization Issue

查看:70
本文介绍了Cosmos DB Newtonsoft反序列化问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在CosmosDb遇到一个奇怪的问题,无法反序列化我的课程.

I am having a strange issue with CosmosDb unable to deserialise my class.

我得到的错误是

无法创建类型为TestApp.Entities.IVisitItem的实例.类型是 接口或抽象类,无法实例化

Could not create an instance of type TestApp.Entities.IVisitItem. Type is an interface or abstract class and cannot be instantiated

启动类中有以下代码

 JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
        {
            TypeNameHandling = TypeNameHandling.Auto
        };

当我在数据浏览器中查看文档时,我可以看到类型信息已正确保存

And when I look in the Data Explorer and look at my document, I can see that the type information is saved correctly

  "VisitItems": [
            {
                "$type": "TestApp.Entities.NoteVisitItem, TestApp.Entities",
                "Note": "fsfsdfdsfsdf",
                "VisitId": "22931c75-efb4-59ea-5b1b-7533bd8bb570",
                "VisitItemType": "Note",
                "Created": "0001-01-01T00:00:00",
                "CreatedById": null,
                "CreatedByName": null,
                "Id": "1e6233cf-e970-4b9f-b60b-a8fb62c94c81"
            }
        ]

如果有人可以阐明我需要做些什么才能正确反序列化,将不胜感激.

If anyone can shed any light on what else I need to be doing to get this to deserialise correctly it would be appreciated.

顺便说一句,这是一个使用Microsoft.Azure.DocumentDB/2.0.0-preview2的.net核心2.1项目.

BTW this is a .net core 2.1 project using Microsoft.Azure.DocumentDB/2.0.0-preview2.

我在所有项目上都使用NewtonsoftJson 11.0.2,它看起来与DocumentDB库所使用的版本相同.

I am using NewtonsoftJson 11.0.2 on all projects and this looks to be the same version the DocumentDB libraries are using.

更新-这是我的数据访问代码

Update -- here is my data access code

  public class CosmosDocumentDbClient : IDbClient
{
    private readonly ConcurrentDictionary<string,Uri> _collectionLinks = new ConcurrentDictionary<string, Uri>();
    private readonly IList<IDisposable> _disposables = new List<IDisposable>();
    private DocumentClient _client;
    private string _databaseId;

    public CosmosDocumentDbClient(IConfigurationRegister configurationRegister)
    {
        var subscription = configurationRegister.Configuration<CosmosDbConfiguration>().Subscribe(c =>
        {
            this._databaseId = c.DatabaseId;
            this._client = new DocumentClient(new Uri(c.EndpointUri), c.Key);

            this.InitialiseDb(this._client, c.DatabaseId, "Case", "Owner").Wait();
        });

        _disposables.Add(subscription);
    }

    public async Task Initialise()
    {
    }

    public IQueryable<TEntity> GetCollection<TEntity>()
    {
        return this._client.CreateDocumentQuery<TEntity>(GetCollectionLink(typeof(TEntity).Name));
    }

    public async Task<List<TEntity>> ToListAsync<TEntity>(Func<IQueryable<TEntity>, IQueryable<TEntity>> items)
    {
        return  await items.Invoke(
            this._client.CreateDocumentQuery<TEntity>(GetCollectionLink(typeof(TEntity).Name)))
            .ToListAsync();
    }

    public async Task<TEntity> FirstOrDefaultAsync<TEntity>(IQueryable<TEntity> query)
    {
        return (await query.Take(1).ToListAsync()).FirstOrDefault();
    }

    public async Task<TEntity> Get<TEntity>(string id)
    {           
       var docUri = UriFactory.CreateDocumentUri(_databaseId, typeof(TEntity).Name,id);
       return await _client.ReadDocumentAsync<TEntity>(docUri);
    }

    public async Task Insert<TEntity>(TEntity entity) where TEntity : IEntity
    {
        await _client.UpsertDocumentAsync(GetCollectionLink(typeof(TEntity).Name), entity);
    }

    public  async Task Update<TEntity>(TEntity entity) where TEntity : IEntity
    {
        try
        {
            var docUri = UriFactory.CreateDocumentUri(_databaseId, typeof(TEntity).Name,entity.Id);
            await _client.ReplaceDocumentAsync(docUri, entity);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }

    }

    private async Task InitialiseDb(DocumentClient client, string databaseId, params string[] collectionIds)
    {
        await client.CreateDatabaseIfNotExistsAsync(new Database() {Id = databaseId});

        foreach (var collectionId in collectionIds)
        {
            await client.CreateDocumentCollectionIfNotExistsAsync(
                UriFactory.CreateDatabaseUri(databaseId), new DocumentCollection {Id = collectionId});
        }
    }

    private Uri GetCollectionLink(string collectionName)
    {
        if (!_collectionLinks.ContainsKey(collectionName))
        {
            _collectionLinks.TryAdd(collectionName,
                UriFactory.CreateDocumentCollectionUri(_databaseId, collectionName));
        }
        return _collectionLinks[collectionName];
    }

推荐答案

因此,正如我们通过评论所得出的结论.

So, as we concluded through comments.

CosmosDB的DocumentClient具有其自己的JsonSerialiser设置对象,您需要在其中配置TypeNameHandling设置.

The DocumentClient of CosmosDB has it's own JsonSerialiser settings object which is where you need to configure the TypeNameHandling setting.

仅将其设置为JsonConvert.DefaultSettings级别将使其可以在序列化上使用,但在反序列化期间将失败.

Setting it only on the JsonConvert.DefaultSettings level will make it work on serialisation but it fails during deserialisation.

DocumentClient级别添加它可以解决此问题.

Adding it at the DocumentClient level will fix the issue.

这篇关于Cosmos DB Newtonsoft反序列化问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆