我在CosmosDb中遇到一个奇怪的问题,无法反序列化我的课程。
我得到的错误是
无法创建类型为TestApp.Entities.IVisitItem的实例。类型是 接口或抽象类,无法实例化
启动类中有以下代码
JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Auto
};
当我在数据浏览器中查看文档时,我可以看到类型信息已正确保存
"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"
}
]
如果有人可以阐明我需要做些什么才能正确反序列化,将不胜感激。
顺便说一句,这是一个使用Microsoft.Azure.DocumentDB / 2.0.0-preview2的.net核心2.1项目。
我在所有项目上都使用NewtonsoftJson 11.0.2,它看起来与DocumentDB库所使用的版本相同。
更新-这是我的数据访问代码
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];
}
答案 0 :(得分:2)
所以,正如我们通过评论所总结的。
CosmosDB的DocumentClient
有自己的JsonSerialiser
设置对象,您需要在其中配置TypeNameHandling
设置。
仅将其设置为JsonConvert.DefaultSettings
级别将使其可以在序列化上使用,但在反序列化期间将失败。
在DocumentClient
级添加它可以解决此问题。