Невозможно вызвать метод api post, у которого есть параметр класса с атрибутом [frombody] в mvc ядра asp.net

Я разрабатываю API в asp.net core mvc для онлайн-бронирования. Но когда я пытаюсь добавить бронирование из метода публикации API, я получаю сообщение об ошибке:

WebException: The remote server returned an error: (415) Unsupported Media Type. System.Net.HttpWebRequest.GetResponse()

Всего 2 проекта:

Проект 1

В моем методе действий API есть метод публикации с атрибутом [FromBody]. Мне нужно вызвать этот метод и передать объект бронирования.

Определение метода:

[HttpPost]
public Reservation Post([FromBody] Reservation res) =>
repository.AddReservation(new Reservation
{
    Name = res.Name,
    FromLocation = res.FromLocation,
    ToLocation = res.ToLocation
});

Проект 2 В проекте 2 я хочу вызвать этот метод API. Для этого я создал форму в представлении, чтобы заполнить имя, от местоположения до значений местоположения. Затем на контроллере я должен вызвать метод API (указанный выше).

Код контроллера:

[HttpPost]
public IActionResult AddReservation(Reservation reservation)
{
    HttpWebRequest apiRequest = WebRequest.Create("http://localhost:8888/api/Reservation") as HttpWebRequest;
        apiRequest.Method = "Post";
        string parameters = "Name=" + reservation.Name + "Image=" + reservation.Image + "&FromLocation=" + reservation.FromLocation + "&ToLocation=" + reservation.ToLocation;
        byte[] byteArray = Encoding.UTF8.GetBytes(parameters);
        apiRequest.ContentType = "application/x-www-form-urlencoded";
        apiRequest.ContentLength = byteArray.Length;
        // Add the post data to the web request
        Stream postStream = apiRequest.GetRequestStream();
        postStream.Write(byteArray, 0, byteArray.Length);
        postStream.Close();

        string apiResponse = "";
        using (HttpWebResponse response = apiRequest.GetResponse() as HttpWebResponse)
        {
            StreamReader reader = new StreamReader(response.GetResponseStream());
            apiResponse = reader.ReadToEnd();
        }
        return RedirectToAction("Index");
}

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

Но когда я запускаю команду powershell, она работает:

PM> Invoke-RestMethod http://localhost:8888/api/Reservation -Method POST -Body (@{Name="Anne"; ToLocation="Meeting Room 4"} | ConvertTo-Json) -ContentType "application/json"

Пожалуйста помоги?

попробуйте заменить apiRequest.ContentType = "application/x-www-form-urlencoded"; на apiRequest.ContentType = "application/json";

Guru Stron 13.09.2018 20:22

@GuruStron не помогло, проверил, выполнив apiRequest.ContentType = "application / json"; Я получаю внутреннюю ошибку сервера 500.

Joe Clinton 13.09.2018 20:28
1
2
1 305
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В первом случае вы кодируете тело запроса как x-www-form-urlencoded, а во втором - как application/json. Одно и то же действие не может отвечать обоим. Поскольку параметр украшен [FromBody], вам следует использовать application/json, поэтому команда powershell сработала.

Если вы на самом деле хотетьx-www-form-urlencoded, то удалите атрибут [FromBody]. Если вам действительно нужно поддерживать оба, вам понадобятся два отдельных маршрута:

private Reservation PostCore(Reservation res)
{
    // do something
}

[HttpPost("json")]
public Reservation PostJson([FromBody] Reservation res) => PostCore(res);

[HttpPost("")]
public Reservation PostForm(Reservation res) => PostCore(res);

Не помогло, поменял на 'apiRequest.ContentType = "application / json";' но теперь он выдает ошибку - удаленный сервер возвратил ошибку: (500) Internal Server Error.

Joe Clinton 13.09.2018 20:28

Команда powershell работает, что означает, что в коде HttpWebRequest есть ошибка. Я отправляю параметры в виде массива байтов (byte [] byteArray). Это правильно или мне нужно это изменить?

Joe Clinton 13.09.2018 20:35

Хорошо, я думаю, что моя вина в том, что я не на 100% откровенен. Он должен быть закодирован как application/jsonа также, он действительно должен быть быть JSON. У ваших строковых параметров нет, поэтому ASP.NET Core задыхается, пытаясь проанализировать его как JSON.

Chris Pratt 13.09.2018 21:11
Ответ принят как подходящий

В вашем POST-коде есть две проблемы, сначала я упомянул в комментариях, а Крис в своем ответе.

Во-вторых, как вы создаете тело своего запроса, используйте что-то вроде этого:

var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";

using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
    string json = "{\"user\":\"test\"," +
                  "\"password\":\"bla\"}";

    streamWriter.Write(json);
    streamWriter.Flush();
    streamWriter.Close();
}

var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    var result = streamReader.ReadToEnd();
}

код взят из этого ответчик

Также вы можете использовать Json.Net для сериализации вашего бронирования (если все имена и типы полей совпадают)

Отлично, сработало. Мне пришлось отправить параметры в json, поэтому здесь нужно использовать код streamWriter. Спасибо.

Joe Clinton 13.09.2018 20:48

Идеально!!!! получал "ошибку сервера" много пытался, но, в конце концов, у меня это сработало +1

Haseeb 03.02.2021 12:23

@Haseeb рад, что это было полезно и для вас!

Guru Stron 08.02.2021 11:29

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