【问题标题】:Is there a way to reset $id in JSON response for each HTTP Request? JsonSerializerSettings = PreserveReferencesHandling.Objects有没有办法为每个 HTTP 请求重置 JSON 响应中的 $id? JsonSerializerSettings = PreserveReferencesHandling.Objects
【发布时间】:2020-01-21 00:27:16
【问题描述】:

XYZController.cs

[HttpPost]
public async Task<ActionResult> Post([FromBody] T inputContext)
{
       var outputContext = Process(inputContext);
       return StatusCode(200, outputContext );
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
     services.AddMvc().AddJsonOptions(options =>
            {
                UpdateJsonSettings.ConfigureJsonFormatter(options.SerializerSettings);
            });
}

UpdateJsonSettings.cs

internal static void ConfigureJsonFormatter(JsonSerializerSettings settings)
{
       settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
       settings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
       settings.Converters.Add(new StringEnumConverter());
}

XYZ 控制器尝试 1 的 HttpResponse:

{ "$id": "1", “账单”: { "$id": "2", "type": "TYPE1",

XYZ 控制器尝试 2 的 HttpResponse:-- 不以 $id 1 开头

{ "$id": "28", “账单”: { "$id": "29", "type": "TYPE1",

XYZ 控制器尝试 3 的 HttpResponse:- 不以 $id 1 开头

{ "$id": "55", “账单”: { "$id": "56", "type": "TYPE1",

我正在使用 Newtonsoft.Json (11.0.2)

【问题讨论】:

  • 您能说明如何获得响应(您要重现的 Web api 代码)吗?
  • 我已添加控制器信息。
  • 这不能使用提供的示例代码/json设置生成。 $id 在每次调用 JsonConvert.Serialize 时都会为我重置。您需要提供更多信息,例如输入和输出模型是什么样的? Process 方法大致做了什么?
  • 我有另一个控制器正在返回运行状况检查。 [HttpGet] public async Task GetHealth() { 动态 healthStatus = true;返回确定(健康状态); } } 这也返回上次调用中引用的 $id。
  • [Route("api/[controller]")] [ApiController] public class HealthController : ControllerBase { } 控制器注册签名

标签: asp.net-core-webapi asp.net-core-2.1


【解决方案1】:

我学到了很多东西!

问题出在 StatusCode 方法中,它正在返回 ObjectResult。将方法签名更改为 IActionResult 并返回 JsonResult 后,它工作正常。此外,API 性能也得到了改进。

[HttpPost]
public async Task<IActionResult> Post([FromBody] T inputContext)
{
       var outputContext = Process(inputContext);
       var jsonResult = new JsonResult(outputContext);
       jsonResult.StatusCode = 200;
       return jsonResult;
}

【讨论】:

    【解决方案2】:

    我打开了thread on Github 来讨论这个问题。

    基本上,StatusCode 缓存$id 值的问题是因为this line of code

    出于性能原因,NewtonsoftJsonOutputFormatter 选择缓存用于序列化对象的JsonSerializer。这还将缓存DefaultReferenceResolver 及其内部计数器。

    正如我在 Github 问题中所说,有一种方法可以使用自定义 IReferenceResolver 为每个请求解决此问题。但是,要解决每个请求还有很长的路要走,因为解析器也缓存在单例/静态上下文中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多