使用 .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

如果您使用.NET Core 3.1,请使用版本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的主要内容,如果未能解决你的问题,请参考以下文章

拿下了!国内首个AI时尚杂志封面

拿下了!国内首个AI时尚杂志封面

使用 .NET 在 Angular 和 Cosmos DB 之间传递“纯”(无类)json

如何将 Auth0 与 .net 核心 API 和 Angular 一起使用?

在同一个端口上运行 Angular 和 ASP.NET Web API

如何使用 Angular 7 保持 AngularCLIServer 在 asp.net 核心上的构建之间运行