2
votes

I try to call my API in a method but i get the error: {StatusCode: 415, ReasonPhrase: 'Unsupported Media Type'. I have been looking around and found a lot of people have had the same problem but it have been solved by adding the media type when creating the StringContent. I have set the string content and i still get the error.

Here is my method where i try to call the API:

    [HttpGet]
    public async Task<ActionResult> TimeBooked(DateTime date, int startTime, int endTime, int id)
    {

        var bookingTable = new BookingTableEntity
        {
            BookingSystemId = id,
            Date = date,
            StartTime = startTime,
            EndTime = endTime
        };

        await Task.Run(() => AddBooking(bookingTable));

        var url = "http://localhost:60295/api/getsuggestions/";

        using (var client = new HttpClient())
        {
            var content = new StringContent(JsonConvert.SerializeObject(bookingTable), Encoding.UTF8, "application/json");
            var response = await client.GetAsync(string.Format(url, content));
            string result = await response.Content.ReadAsStringAsync();

            var timeBookedModel = JsonConvert.DeserializeObject<TimeBookedModel>(result);

            if (response.IsSuccessStatusCode)
            {
                return View(timeBookedModel);
            }
        }

And my API method:

    [HttpGet]
    [Route ("api/getsuggestions/")]
    public async Task<IHttpActionResult> GetSuggestions(BookingTableEntity bookingTable)
    {
        //code
    }

I have been using the same code to call my other method and it has been working fine except in this case. I don't understand the difference between them.

Here is an example where i use basicly the same code and it works.

[HttpGet]
    public async Task<ActionResult> ChoosenCity(string city)
    {
        try
        {
            if (ModelState.IsValid)
            {
                var url = "http://localhost:60295/api/getbookingsystemsfromcity/" + city;

                using (var client = new HttpClient())
                {
                    var content = new StringContent(JsonConvert.SerializeObject(city), Encoding.UTF8, "application/json");
                    var response = await client.GetAsync(string.Format(url, content));
                    string result = await response.Content.ReadAsStringAsync();

                    var bookingSystems = JsonConvert.DeserializeObject<List<BookingSystemEntity>>(result);
                    var sortedList = await SortListByServiceType(bookingSystems);

                    if (response.IsSuccessStatusCode)
                    {
                        return View(sortedList);
                    }
                }
            }
        }

        catch (Exception ex)
        {
            throw ex;
        }

        return RedirectToAction("AllServices");
    }

And the API:

[HttpGet]
    [Route("api/getbookingsystemsfromcity/{city}")]
    public async Task<IHttpActionResult> GetBookingSystemsFromCity(string city)
    {
        //code
    }
2
GET requests can't have bodies, so they can't have content types either. Looks like the server rejects the request as soon as it sees the invalid header and doesn't even try to see whether there's a body. - Panagiotis Kanavos

2 Answers

8
votes

Web API expects client to specify Content-Type header, but you cannot specify this header for HttpClient while making GET request because it doesn't have a body. Even though you specified application/json in StringContent you passed the object incorrectly into request. Consider using POST to fix you problem. And it's a common practice to use POST to transfer complex objects.

Update api to accept POST

[HttpPost]
[Route ("api/getsuggestions/")]
public async Task<IHttpActionResult> GetSuggestions(BookingTableEntity bookingTable)

Update request code

var content = new StringContent(JsonConvert.SerializeObject(city), Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
string result = await response.Content.ReadAsStringAsync();

Note

Don't dispose HttpClient on each request, it's intended to be reused.

1
votes

You are sending a body into a get request which don't have a body parameter. You can pass parameters in the url or query string only.

The second query succeeds because you have passed the city in the url.

You will need to switch the first query into a post request if you want to pass a complex object in the body of the request, or separate the complex object out into parameters and pass them in the url instead