Ниже я публикую данные для двух разных конечных точек 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 и почему оба приложения ведут себя по-разному?
Спасибо,
@ jandrew, у меня есть Newtonsoft in my 3.1 core app, could you please tell me code what I need to configure in
стартап`?
Это в вашем ConfigureServices
методе запуска, services.AddControllers().AddNewtonsoftJson();
. В документах есть раздел, который более подробно описан.
В asp.net core 3.1 значение указывает на токен Json. Я думаю, это объясняет это лучше всего. github.com/dotnet/runtime/issues/31408 Вот ещё объяснение stackoverflow.com/questions/60465030/…
Вы использовали 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.
Они используют разные библиотеки сериализации/десериализации JSON по умолчанию. Net Core 3.1 по умолчанию использует
System.Text.Json
. Если вы хотите использовать Newtonsoft в версии 3.1, вам нужно добавить пакет и настроить его в своем классе Startup. Так будет в вашей ситуации?