HttpGetAttribute 名称属性不适用于路由

问题描述 投票:0回答:3

我有一个名为 WeatherForecast 的 WebAPI 控制器,只需一个操作。操作方法如下:

[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    })
    .ToArray();
}

但是,

HttpGet.Name = "GetWeatherForecast"
应定义路线名称“GetWeatherForecast”,因为我了解
Name
属性对于此属性的用途。

但是 Swagger 向我展示了操作本身根本没有路由: 显示的 URL 为 https://localhost:port/WeatherForecast (通过该URL即可消费服务操作,我使用Postman进行测试)

但是使用设置了

HttpGet
属性的
Name
属性,我希望它是 https://localhost:port/WeaterhForecast/GetWeatherForecast

当我在操作方法上额外使用

Route
属性(
Route("GetWeatherForecast")
)时,操作的路线如下所示:https://localhost:port/WeatherForecast/GetWeatherForecast (现在确实可以通过该 URL 访问服务操作)。

所以,问题是:为什么

Name
属性的
HttpGet
属性没有实现文档所承诺的功能?或者
HttpGetAttribute.Name
的真正用途是什么?

源代码是使用 .NET 6.0 和 VS 2022 编写的,项目类型 ASP.NET Core-Web-API。显示的代码来自项目模板自动创建的控制器。

c# asp.net asp.net-core asp.net-web-api-routing
3个回答
14
投票

您使用

HttpGet
属性的方式:

[HttpGet(Name = "GetWeatherForecast")]

表示您指定

Name
属性,该属性不会更改路由 URL 的生成方式。路由名称可用于使用特定路由生成链接,而不是依赖于基于给定的一组路由值来选择路由。

相反,您应该通过排除命名参数或使用正确的名称来指定

Template
属性:

[HttpGet("GetWeatherForecast")]

或者:

[HttpGet(Template = "GetWeatherForecast")]

0
投票

DavidG 是对的。使用 [HttpGet("GetWeatherForecast")] 而不是 [HttpGet(Name = "GetWeatherForecast")] 对我有用。我在同一个问题上被困了很多天,尝试了很多解决方法,并遵循了互联网上不同论坛中几乎所有可用的建议,但最有效的解决方案是删除控制器内的 Name 属性。

这确实是一个奇怪的事实,使用 [HttpGet(Name = "GetWeatherForecast")] 确实有效,因为它暗示它会起作用,如果你使用类似的东西

routes.MapGet("/api/Pnrlog/{id}", (int id) =>
        {
            return new Pnrlog { PnrlogId = id };
        })
        .WithName("GetPnrlogById");

它也不是那样工作的......


0
投票

并没有回答问题,但添加了一些有趣的内容,这肯定会澄清

Name
Template
目标之间的区别(尽管我无法正式说出它是什么):

删除 Name 属性以使用模板,最终允许通过指定完整路由来访问资源:

https://localhost:7008/WeatherForecast/GetWeatherForecast
。 但是 - 通过单独指定到控制器的路由来访问相同的资源 - 不再返回结果。

简而言之:

  1. 使用
    Name
    属性、
    Get
    方法(名为
    GetWeatherForecast
    ),可以通过单独路由到控制器来访问资源:
    https://localhost:7008/WeatherForecast
    。尝试通过完整路径访问资源失败 (404)。
  2. 使用 Template 属性,可以使用完整路径访问资源:
    https://localhost:7008/WeatherForecast/GetWeatherForecast
    。尝试单独路由到控制器来访问它,失败 (404)。

[HttpGet("GetWeatherForecast")]
//[HttpGet(Name = "GetWeatherForecast")]
© www.soinside.com 2019 - 2024. All rights reserved.