简体   繁体   中英

ASP.Net Core Web API: Unsupported Media Type on GET Request

I just started learning asp.net MVC6 and trying to learn how things work in it. Currently, I'm using the .net 5.0. So this is the WebAPI method and I just added a object parameter weatherForecast to it:

        [BindProperties(SupportsGet = true)]
    public class WeatherForecast
    {

        public int TemperatureC { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

        public string Summary { get; set; }
    }

    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
{
    [HttpGet]
        public IEnumerable<WeatherForecast> Get(WeatherForecast weatherForecast)
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
}

When I sent this method a GET request from a browser or even from a POSTMAN:

http://localhost:1382/WeatherForecast?TemperatureC=12&Summary=HelloWorld

It returns:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
    "title": "Unsupported Media Type",
    "status": 415,
    "traceId": "00-a556c5fbdce0748bf3c7bd0e3200e92-21f4bf6470b534d-00"
}

The funny thing is in PostMan if I add a JSON body with a GET request (just for testing) then this works fine without any error. I read the Microsoft model binding documentation [Here the link][1] and it says: "By default, properties are not bound for HTTP GET requests" so we have to use an attribute [BindProperty(SupportsGet = true)] or [BindProperties(SupportsGet = true)] and even after using this attribute it still doesn't work.

So after digging down, I found an attribute [FromQuery] and after using this with the object parameter weatherForecast it starts working. But I want to know why it's not working without this attribute?

Normally in MVC5 if we don't specify any attribute with parameters like [FromUri] etc then the model binder automatically binds the parameters sent in the query string.

What am I missing here? [1]: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-5.0#targets

You just have problems with routing values. You are using MVC routing but trying to add query string too. I suspect that your url hits a wrong action.

Since I can't see your controller, I can only recommend to add an attribute routing as the most reliable routing

    [Route("~/WeatherForecast/Get")]
    public IEnumerable<WeatherForecast> Get(WeatherForecast weatherForecast)

and use this url

http://localhost:1382/WeatherForecast/Get?TemperatureC=12&Summary=HelloWorld

Update

Since you posted your controller, I recommed you to remove [Route("[controller]")] attribute, or if your startup config doesn't allow to do this change it to

    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase

or for APIs usually

[Route("api/[controller]/[action]")]

in this case you don't need attribute routing , but your urls pattern should be

http://localhost:1382/WeatherForecast/<action>
//or
http://localhost:1382/api/WeatherForecast/<action> //if api added

and forget about REST, it is good for a very simple textbook CRUDE only, in the real life each controller will have much more then 4 actions and you will not be able to find ehough gets and posts.

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