[英]Cosmos DB Newtonsoft Deserialization Issue
I am having a strange issue with CosmosDb unable to deserialise my class. 我遇到一个奇怪的问题,CosmosDb无法反序列化我的班级。
The error I am getting is 我得到的错误是
Could not create an instance of type TestApp.Entities.IVisitItem.
无法创建类型为TestApp.Entities.IVisitItem的实例。 Type is an interface or abstract class and cannot be instantiated
类型是接口或抽象类,无法实例化
I have the following code in my startup class 我的启动课程中有以下代码
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. 如果有人可以阐明我需要做些什么才能正确反序列化,将不胜感激。
BTW this is a .net core 2.1 project using Microsoft.Azure.DocumentDB/2.0.0-preview2. 顺便说一句,这是一个使用Microsoft.Azure.DocumentDB / 2.0.0-preview2的.net核心2.1项目。
I am using NewtonsoftJson 11.0.2 on all projects and this looks to be the same version the DocumentDB libraries are using. 我在所有项目上都使用NewtonsoftJson 11.0.2,它看起来与DocumentDB库所使用的版本相同。
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. 因此,正如我们通过评论得出的结论。
The DocumentClient
of CosmosDB has it's own JsonSerialiser
settings object which is where you need to configure the TypeNameHandling
setting. CosmosDB的
DocumentClient
具有自己的JsonSerialiser
设置对象,您需要在该对象中配置TypeNameHandling
设置。
Setting it only on the JsonConvert.DefaultSettings
level will make it work on serialisation but it fails during deserialisation. 仅在
JsonConvert.DefaultSettings
级别上进行设置将使其在序列化上起作用,但在反序列化期间将失败。
Adding it at the DocumentClient
level will fix the issue. 在
DocumentClient
级别添加它可以解决此问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.