Почему отличается поведение веб-API ASP.NET 2 и веб-API ASP.NET Core 3.1?

Ниже я публикую данные для двух разных конечных точек API, одну из которых мы имеем в приложении ASP.NET Web API 2, а другую — в приложении ASP.NET Core 3.1 Web API.

var data = new Data
            {
                Key = "k1",
                Value = 80
            };

IClient httpClient = new FluentClient("http://localhost:46551/");
var x = httpClient.PostAsync("weatherforecast", data).GetAwaiter().GetResult();

Для обоих приложений веб-API мой класс модели находится ниже, где Value — это object тип, и это мое жесткое требование, я не могу использовать фактический тип.

public class Data
{
    public string Key { get; set; }
    public object Value { get; set; }
}

Когда я отправляю данные в ASP.NET Web API 2 (с .Net 4.6.1), отладчик VS правильно отображает только значение без какой-либо другой полезной нагрузки:

Но для веб-API ASP.NET Core 3.1 отладчик VS показывает совершенно другое представление вместе с ValueKind:

У меня есть требование написать data в формате Json с ожидаемым результатом ниже,

{ "Key":"k1", "Value":80 }

Пока я пытаюсь сериализовать data для веб-API ASP.NET Core 3.1, я получаю следующий вывод:

var ser = JsonConvert.SerializeObject(data);

{ "Key":"k1", "Value": {"ValueKind":4} }

Для приложения ASP.NET Web API 2, хотя я получаю ожидаемый результат.

Вопрос, как получить этот вывод { "Key":"k1", "Value":80 } из приложения ASP.NET Core 3.1 и почему оба приложения ведут себя по-разному?

Спасибо,

Они используют разные библиотеки сериализации/десериализации JSON по умолчанию. Net Core 3.1 по умолчанию использует System.Text.Json. Если вы хотите использовать Newtonsoft в версии 3.1, вам нужно добавить пакет и настроить его в своем классе Startup. Так будет в вашей ситуации?

jdewerth 11.12.2020 05:17

@ jandrew, у меня есть Newtonsoft in my 3.1 core app, could you please tell me code what I need to configure in стартап`?

user584018 11.12.2020 05:20

Это в вашем ConfigureServices методе запуска, services.AddControllers().AddNewtonsoftJson();. В документах есть раздел, который более подробно описан.

jdewerth 11.12.2020 05:26

В asp.net core 3.1 значение указывает на токен Json. Я думаю, это объясняет это лучше всего. github.com/dotnet/runtime/issues/31408 Вот ещё объяснение stackoverflow.com/questions/60465030/…

FrankJames 11.12.2020 05:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
226
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы использовали Newtonsoft ранее? Средство форматирования JSON, которое теперь включено в netcore 3x, используется по умолчанию, если вы явно не включили другой парсер, такой как NewtonSoft. Поведение нового анализатора/парсера по умолчанию имеет ряд отличий от Newtonsoft, но больше всего огорчила мою команду при миграции то, что парсер System.Text.Json НЕ делает предположений при идентификации JSON. Чаще всего это происходило, когда поле иногда могло принимать сложный объект JSON, а также содержать примитивные типы в таких случаях, как логическое или целое число. Конкретным примером для меня была концепция настроек, где это была в основном пара ключ/значение, где ключ был именем параметра, такого как GridSettings, который был большим двоичным объектом и хранился в Postgres как JSON, однако другой параметр, такой как showHidden, был простым истинным или ложный. Newtonsoft по-прежнему будет принуждать это логическое значение к JSON, поскольку модель поддержки и модель объекта объявили его как таковое, тогда как System.Text.Json говорит, что нет, это просто логическое значение, если вы не скажете мне иначе.

Попробуйте внедрить Newtonsoft в качестве синтаксического анализатора в свой IoC/Startup и посмотрите, изменит ли это поведение.

некоторые подробности о различиях в новом парсере: https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnetcore#authentication-newtonsoftjson-types-replaced

Нам также пришлось внести коррективы в наши средства форматирования в определенных сценариях:

пользовательский форматтер: https://code-maze.com/content-negotiation-dotnet-core/

В целом я думаю, что синтаксический анализатор, который не делает никаких предположений, значит хорошо и, вероятно, это хорошо. Однако в моем случае мы просто не были готовы внести все исправления, необходимые для противодействия этому изменению. Таким образом, пока мы придерживаемся старого доброго Newtonsoft.

Другие вопросы по теме