1

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?

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
Joe Clinton
  • 145
  • 1
  • 12
  • 1
    try changing `apiRequest.ContentType = "application/x-www-form-urlencoded";` to `apiRequest.ContentType = "application/json";` – Guru Stron Sep 13 '18 at 18:22
  • @GuruStron it did not helped i checked by doing apiRequest.ContentType = "application/json"; I am getting now internal server 500 error. – Joe Clinton Sep 13 '18 at 18:28

2 Answers2

3

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);
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • It did not helped, i changed it to 'apiRequest.ContentType = "application/json";' but it is now giving error - The remote server returned an error: (500) Internal Server Error. – Joe Clinton Sep 13 '18 at 18:28
  • The powershell command is working that mean the HttpWebRequest code has some error. I am sending the parameters as byte array (byte[] byteArray). Is it right or do i need to change it? – Joe Clinton Sep 13 '18 at 18:35
  • OK, I guess my fault for not being 100% explicit. It needs to be encoded as `application/json` *and* it actually needs to *be* JSON. Your string parameters are not, so ASP.NET Core is choking on trying to parse it as JSON. – Chris Pratt Sep 13 '18 at 19:11
2

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)

Guru Stron
  • 102,774
  • 10
  • 95
  • 132