我刚刚开始学习 asp.net MVC6 并尝试了解其中的工作原理。目前我正在使用 .NET 5.0。
这就是 WebAPI 方法,我刚刚向其中添加了一个对象参数 weatherForecast:
[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();
}
}
当我从浏览器甚至邮递员向此方法发送 GET 请求时:
http://localhost:1382/WeatherForecast?TemperatureC=12&Summary=HelloWorld
返回:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
"title": "Unsupported Media Type",
"status": 415,
"traceId": "00-a556c5fbdce0748bf3c7bd0e3200e92-21f4bf6470b534d-00"
}
有趣的是,在 PostMan 中,如果我添加带有 GET 请求的 JSON 正文(仅用于测试),那么它可以正常工作,不会出现任何错误。 我阅读了 Microsoft 模型绑定文档 [这里是链接][1],它说: “默认情况下,属性不绑定 HTTP GET 请求” 所以我们必须使用属性 [BindProperty(SupportsGet = true)] 或 [BindProperties(SupportsGet = true)] 即使使用此属性后它仍然不起作用。
因此,在深入挖掘之后,我发现了一个属性 [FromQuery],并将其与对象参数 weatherForecast 一起使用后,它开始工作。但我想知道为什么没有这个属性就不起作用?
通常在 MVC5 中,如果我们不使用 [FromUri] 等参数指定任何属性,则模型绑定器会自动绑定查询字符串中发送的参数。
我在这里缺少什么? [1]:https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-5.0#targets
您只是遇到了路由值的问题。您正在使用 MVC 路由,但也尝试添加查询字符串。我怀疑你的网址执行了错误的操作。
由于我看不到你的控制器,所以我只能建议添加一个属性路由作为最可靠的路由
[Route("~/WeatherForecast/Get")]
public IEnumerable<WeatherForecast> Get(WeatherForecast weatherForecast)
并使用此网址
http://localhost:1382/WeatherForecast/Get?TemperatureC=12&Summary=HelloWorld
更新
既然您发布了控制器,我建议您删除 [Route("[controller]")] 属性,或者如果您的启动配置不允许这样做,请将其更改为
[ApiController]
[Route("[controller]/[action]")]
public class WeatherForecastController : ControllerBase
或者通常用于 API
[Route("api/[controller]/[action]")]
在这种情况下,您不需要属性路由,但您的 url 模式应该是
http://localhost:1382/WeatherForecast/<action>
//or
http://localhost:1382/api/WeatherForecast/<action> //if api added
忘记 REST,这对于非常简单的教科书 CRUDE 来说很有用,在现实生活中,每个控制器将有超过 4 个操作,并且您将无法找到足够的获取和帖子。