使用 .NET 在 Angular 和 Cosmos DB 之间传递“纯”(无类)json
Posted
技术标签:
【中文标题】使用 .NET 在 Angular 和 Cosmos DB 之间传递“纯”(无类)json【英文标题】:Passing "pure" (class-less) json between Angular and Cosmos DB with .NET 【发布时间】:2021-12-27 13:18:07 【问题描述】:我有 json 数据位于 Cosmos DB 中,我想将其传送到 Angular 应用程序。 Angular 应用程序可以处理各种 json 结构,并允许用户修改数据并推送回 Cosmos(通过 API - 见下文)。
我正在尝试构建一个简单的 C# API,它将仅用于从 Cosmos 查询数据并将“原始”json 推送回 angular,而无需为我存储的每种类型的 json 对象创建类。 API 只是将数据从 Cosmos 传递给 Angular 并将数据从 Angular 推回 Cosmos 的机制。
我还没有找到一种简单的方法来做到这一点,因为所有方法似乎都需要一个结构化的类对象来从 Cosmos 检索数据并将其保存回来。
有什么建议可以实现吗?
-- 编辑--
这是我在动态中使用的一些示例代码,它适用于检索数据,但它不会在中间件中序列化为 Json(请参阅下面的异常)。
public async Task<dynamic> GetItemAsync(string id)
try
var response = await this._container.ReadItemAsync<dynamic>(id, new PartitionKey(id));
return response.Resource;
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
return null;
[15:12:25 ERR] 在执行 要求。
System.NotSupportedException:集合类型 不支持“Newtonsoft.Json.Linq.JObject”。在 System.Text.Json.JsonPropertyInfoNotNullable`4.GetDictionaryKeyAndValueFromGenericDictionary(WriteStackFrame& writeStackFrame、String& 键、Object& 值)在 System.Text.Json.JsonPropertyInfo.GetDictionaryKeyAndValue(WriteStackFrame& writeStackFrame、String& 键、Object& 值)在 System.Text.Json.JsonSerializer.HandleDictionary(JsonClassInfo elementClassInfo,JsonSerializerOptions 选项,Utf8JsonWriter 作家,WriteStack& 状态)在 System.Text.Json.JsonSerializer.Write(Utf8JsonWriter 作家,Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions 选项,WriteStack& 状态)在 System.Text.Json.JsonSerializer.WriteAsyncCore(流 utf8Json,对象 值,类型 inputType,JsonSerializerOptions 选项, CancellationToken 取消令牌)在 Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext 上下文,编码选择编码)在 Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext 上下文,编码选择编码)在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|21_0(ResourceInvoker 调用者,IActionResult 结果)在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker 调用者,任务 lastTask,下一个状态,作用域范围,对象状态,布尔值 已完成)在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed 上下文)在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& 范围, Object& 状态, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
我也尝试将 System.Text.JSON 与 JSONDocument 一起使用,但在检索数据时它抱怨它需要一个构造函数作为类的一部分?
【问题讨论】:
你可以用动态吗? 您使用的是 NewtonSoft.JSON 还是 System.Text.Json?两者都可以处理。您可以在 Newtonsoft 中使用 JObject 并且......我认为它是 System.Text.Json 的 JElement(现在不确定)。 我都试过了。 NewtonSoft.JSON 通过尝试在 JSObject 中反序列化的异常。 System.Text.Json 在使用 JSONDocument 时抱怨构造函数 至于使用动态...在将响应发送到角度应用程序之前尝试序列化时具有相同的 JSObject 异常 那么我认为我们需要一些代码来研究。 【参考方案1】:发生这种情况的原因是因为Microsoft.Azure.Cosmos
仍然使用Newtonsoft.Json
进行序列化和反序列化。
您的 ASP.NET Core 应用程序正在使用 System.Text.Json
。在 ASP.NET Core 应用程序中使用 Cosmos 时,我将切换解决方案以使用 Newtonsoft.Json
而不是 System.Text.Json
。你可以通过添加这个包来做到这一点:
Microsoft.AspNetCore.Mvc.NewtonsoftJson
3.1.*
如果您使用的是 .NET5,请使用版本 5.0.*
如果您使用的是 .NET6,请使用版本
6.0.*
然后,在您的Startup.cs
中,在ConfigureServices()
方法中更改:
public void ConfigureServices(IServiceCollection services)
// ...
services.AddControllers();
// ...
到这里:
public void ConfigureServices(IServiceCollection services)
// ...
services.AddControllers().AddNewtonsoftJson();
// ...
由于您只想按原样返回对象,请将您的代码更改为:
public async Task<object> GetItemAsync(string id)
try
var response = await this._container.ReadItemAsync<object>(id, new PartitionKey(id));
return response.Resource;
catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
return null;
无需使用dynamic
。只需使用object
。
【讨论】:
谢谢你会试一试,让你知道 这成功了!谢谢以上是关于使用 .NET 在 Angular 和 Cosmos DB 之间传递“纯”(无类)json的主要内容,如果未能解决你的问题,请参考以下文章
使用 .NET 在 Angular 和 Cosmos DB 之间传递“纯”(无类)json
如何将 Auth0 与 .net 核心 API 和 Angular 一起使用?