Есть ли способ сбросить $ id в JSON ответе для каждого HTTP-запроса? JsonSerializerSettings = PreserveReferencesHandling.Objects - PullRequest
5 голосов
/ 21 января 2020

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());
}

HttpResponse для контроллера XYZ Попробуйте 1:

{"$ id": "1", "bill": {"$ id": "2", "type": "TYPE1",

HttpResponse для контроллера XYZ Попробуйте 2: - делает не начинать с $ id 1

{ "$ id": "28", <--- НЕ УВЕРЕН, ПОЧЕМУ ПО ВТОРОМУ ЗАПРОСУ $ ID начинается с 28 :( -> " bill ": {" $ id ":" 29 "," type ":" TYPE1 ",

HttpResponse для контроллера XYZ Попытка 3: - не начинается с $ id 1

{ "$ id": "55", <--- НЕ УВЕРЕН, ПОЧЕМУ ПО ВТОРОМУ ЗАПРОСУ $ ID начинается с 55 :( -> "bill": { "$ id": "56" , "type": "TYPE1",

Я использую Newtonsoft. Json (11.0.2)

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Я открыл поток на Github , чтобы обсудить это.

В принципе, проблема с StatusCode кэшированием значений $id заключается в том, что эта строка кода .

Из соображений производительности NewtonsoftJsonOutputFormatter решил кэшировать JsonSerializer, используемый для сериализации объектов. Это также кеширует DefaultReferenceResolver и его внутренний счетчик.

Как я уже говорил в выпуске Github, есть способ обойти это для каждого запроса, используя пользовательский IReferenceResolver. Но для каждого запроса было бы далеко, так как распознаватель также кэшируется в контексте singleton / stati c.

2 голосов
/ 07 апреля 2020

Я научился этому нелегко!

Ошибка была в методе 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...