C # WebClient с использованием UploadString для вызова метода HttpPost из ApiController также в C #. Ошибка 415 или 400 - PullRequest
2 голосов
/ 25 апреля 2019

Я хочу, чтобы в C # вызывался ApiController также в C #, но я получаю ошибку 415 или 400 при загрузке Json с использованием метода UploadString из экземпляра WebClient.

Код сервера - это автоматически сгенерированный вызов TestController. Этот файл в точности соответствует тому, как его генерирует Visual Studio 2019.

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    // GET: api/Test
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // POST: api/Test
    [HttpPost]
    public void Post([FromBody] string value)
    {
    }
    ...
}

Код клиента выглядит так:

WebClient client = new WebClient();
client.UploadString("https://localhost:44345/api/Test", "ABC");   // Edit: "ABC" is not a valid JSON

Я получаю System.Net.WebException: 'Удаленный сервер возвратил ошибку: (415) Неподдерживаемый тип носителя.'

Так что после поиска в Google большинство подсказок - ContentType не получает указание, если я добавлю

client.Headers[HttpRequestHeader.ContentType] = "application/json";

Я получаю System.Net.WebException: 'Удаленный сервер возвратил ошибку: (400) Неверный запрос.'

Есть подсказка?

Похоже, что проблема связана с POST / PUT / PATCH ... если я сделаю GET, он работает и возвращает мне образец данных ["value1","value2"]

Edit: я не придерживаюсь метода WebClient.UploadString, но мне бы хотелось решение, которое не включало бы 25 строк пользовательского кода ... Я имею в виду, я не могу поверить, что это так сложно, где вы можете это сделать в jQuery с использованием одной строки.

Ответы [ 2 ]

5 голосов
/ 29 апреля 2019

Я получаю System.Net.WebException: 'Удаленный сервер возвратил ошибку: (415) Неподдерживаемый тип носителя.'

Когда вы используете [FromBody], заголовок Content-Type используется, чтобы определить, как анализировать тело запроса. Когда Content-Type не указан, процесс связывания модели не знает, как использовать тело, и поэтому возвращает 415.

Я получаю System.Net.WebException: 'Удаленный сервер возвратил ошибку: (400) Неверный запрос.'

Установив заголовок Content-Type на application/json, вы указываете процессу привязки модели обрабатывать данные как JSON, но сам ABC не является допустимым JSON. Если вы просто хотите отправить строку в кодировке JSON, вы также можете заключить значение в кавычки, например:

client.UploadString("https://localhost:44345/api/Test", "\"ABC\"");

"ABC" является допустимой строкой JSON и будет принят вашим базовым API ASP.NET.

2 голосов
/ 29 апреля 2019

Простое решение:

Укажите Content-type в заголовке при вызове API,

            WebClient client = new WebClient();
            client.Headers.Add("Content-Type", "text/json");
            client.UploadString("https://localhost:44345/api/Test", "\"ABC\"");

Изменить:

Не используйте атрибут [From_Body], так как он имеет ужасную возможность обработки ошибок, см Здесь .

Если в теле запроса есть недопустимый ввод (синтаксическая ошибка, неподдерживаемый ввод), то он выдаст 400 и 415 за неправильный запрос и неподдерживаемый контент. по той же причине он может принимать значение null как ввод из тела запроса, если он не понимает формат.

Итак, удалите атрибут и попробуйте загрузить строку в простом формате, так как она принимает только строку, и вам не требуется указывать атрибут Content-Type при выполнении запроса.

[HttpPost]
 public void Post(string value)
 {

 }

И называйте это так, как вы звонили в исходном сообщении.

WebClient client = new WebClient();
client.UploadString("https://localhost:44345/api/Test", "ABC");
...