Контроллер API не может прочитать Json из тела POST - PullRequest
0 голосов
/ 05 ноября 2018

Фон

Я отправляю JSON в моем теле на мой контроллер API, но получаю следующую ошибку.

{"": ["При анализе значения обнаружен неожиданный символ: {. Path '', строка 1, позиция 1. "]}

Мой HTTP-запрос

HttpClient client = new HttpClient();
HttpRequest httpRequest;
HttpResponseMessage httpResponse = null;
httpRequest = new HttpRequest("", HostnameTb.Text, null);

var values = new Dictionary<string, string>
{
    { "APIKey", APIKeyTb.Text }
};

string json = JsonConvert.SerializeObject(values);
StringContent content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
httpResponse = client.PostAsync(HostnameTb.Text, content).Result;

var responseString = await httpResponse.Content.ReadAsStringAsync();

Мой контроллер выглядит следующим образом.

[HttpPost]
public void Post([FromBody] string value)
{
  //Never gets here.
}

Json в теле.

{ "APIKey": "1283f0f8 ..."}

Вопрос

Я бы предпочел использовать функциональность .Net Core [From Body], а не получать контент вручную.

Я ожидаю, что строка JSON будет доступна в параметре string Value.

Что мне не хватает?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Это не так, как это работает. [FromBody] вызывает сериализатор для десериализации тела запроса. Затем связыватель модели пытается связать это с параметром. Здесь это невозможно, потому что вы привязываетесь к строке, а тело запроса - это словарь. По сути, то, что происходит под капотом (псевдокод):

value = JsonConvert.DeserializeObject<string>(dictionaryAsJson);

Вы получаете ошибку десериализации из JSON.NET, потому что он не может проанализировать JSON в строку.

Если вы хотите, чтобы значение представляло собой строку, то вы должны опубликовать что-то вроде text/plain вместо application/json. В противном случае вам нужно будет привязаться к типу, который фактически представляет входящий объект JSON, который здесь будет Dictionary<string, string>.

0 голосов
/ 05 ноября 2018

ASP.NET Core пытается десериализовать {"APIKey":"1283f0f8..."} из JSON в значение string и завершается неудачно, поскольку ожидает, что ввод является допустимой строкой JSON.

Другими словами, если бы ваше тело было "{\"APIKey\":\"1283f0f8...\"}", вы бы имели строку JSON во входной переменной, как вы ожидаете.

Чтобы получить значение APIKey без изменения HTTP-запроса, создайте тип ввода:

public class Input
{
    public string ApiKey { get; set; }
}

и используйте это как ввод действия вашего контроллера:

[HttpPost]
public void Post([FromBody] Input input)
{
    var apiKey = input.ApiKey;
    // etc
}

Либо измените HTTP-запрос на отправку string:

// ...
var content = new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json");
// ...

Обратите внимание на использование JsonConvert.SerializeObject() вместо ToString(); "foo".ToString() - это всего лишь "foo", а вы хотите "\"foo\"".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...