简体   繁体   中英

Unable to call API Post Method that has a class parameter with [FromBody] attribute in asp.net core mvc

I am developing an API in asp.net core mvc for doing online reservations. But when I am trying to add a reservation from the API post method I am getting error:

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

There are 2 projects:

Project 1

There is a post method in my API action method that a [FromBody] attribute. I have to call this method and pass the reservation object.

The method definition is :

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

Project 2 In project 2 I want to call this API method. For that I have created a form in the view to fill name, from location and to location values. Then On the controller I have to call the API method (given above).

The controller code is:

[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");
}

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

But when I am running powershell command then it works:

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

Please help?

In the former you're encoding the request body as x-www-form-urlencoded and in the latter as application/json . The same action cannot respond to both. Since the param is decorated with [FromBody] , application/json is the one you should be using, which is why the powershell command worked.

If you actually want x-www-form-urlencoded , then remove the [FromBody] attribute. If you actually need to support both, you'll need two separate routes:

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);

There are two issues in your POST code, first I mentioned in comments and Chris in his answer.

Second one is how you generate your request's body, use something like this:

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();
}

code taken form this anwser

Also you can use Json.Net to serialize your reservation(if all fields names and types match)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM