Отправка json в API в виде строки приводит к ошибке, но отправка объекта dotnet не приводит к ошибке

Язык: C# .net framework 4.8 Visual Studio 2019.

Я пытался отправить json в API, и если я отправлю его как строку:

string jsonString = JsonConvert.SerializeObject(dataToSend, Formatting.Indented);


var result = await urlApi.
          WithTimeout(TimeSpan.FromSeconds(timeout)).
          PostJsonAsync(jsonString).
          ReceiveString();

ПРИМЕЧАНИЕ. dataToSend — это объект dotnet. Я использую json-фреймворк Newtonsoft: https://www.newtonsoft.com/json , чтобы сериализовать объект в json. Я использую flurl: https://flurl.dev/, чтобы отправить json.

Удаленный хост отвечает с ошибкой:

{
    "Status": "-1",
    "Description": "System.NullReferenceException: Object reference not set to an instance of an object.",
    "Result": null
}

Однако, когда я отправляю объект напрямую:

var result = await urlApi.
         WithTimeout(TimeSpan.FromSeconds(timeout)).
         PostJsonAsync(dataToSend).
         ReceiveString();

ПРИМЕЧАНИЕ. dataToSend — это объект dotnet.

Я не получаю никаких ошибок.

Я хочу знать, почему отправка json в виде строки вызывает ошибку.

Ты знаешь почему?

¿Как я могу это узнать?

Я сильно подозреваю, что если вы посмотрите на HTTP-запрос в сети, вы увидите, что JSON представляет собой именно то, что вы сказали: строку. Я подозреваю, что это будет что-то вроде: "{ \"x\": \"Some value\", \"y\": \"Some other value\" }" (включая все кавычки и обратную косую черту). Это представление строки в формате JSON.

Jon Skeet 17.05.2024 18:20

Согласен, похоже, вы дважды сериализуете свой JSON. Вопрос JSON.NET Parser, похоже, выполняет двойную сериализацию моих объектов занимается этим на стороне сервера; по сути вы делаете то же самое на стороне клиента.

dbc 17.05.2024 18:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Ваша проблема в том, что вы дважды сериализуете свой JSON. Используемый вами метод расширения, GeneratedExtensions.PostJsonAsync(url этой строки, тело объекта, ...), работает следующим образом:

Создает FlurlRequest и отправляет асинхронный запрос POST.
URL - Этот URL.
body — объект, представляющий тело запроса, который будет сериализован в JSON.

Поскольку ваш jsonString уже сериализован в JSON, он сериализуется второй раз как строковый литерал JSON, в результате чего удаленный хост возвращает ошибку, которую вы видите.

Если по какой-то причине вам нужно сериализовать JSON вручную, вы можете опубликовать его с помощью Flurl.Http.Content.CapturedJsonContent:

var result = await urlApi.
    WithTimeout(TimeSpan.FromSeconds(timeout)).
    PostAsync(new CapturedJsonContent(jsonString)).
    ReceiveString();

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