Kon*_*ten 18 c# routes http-get .net-core asp.net-core
当我使用HttpGet(...)时,智能感知告诉我,除了第一个参数(即pattern )之外,我还有name和order。虽然后者对我来说是显而易见的,但我有点不确定参数名称的用途。
转到文档,我看到HttpGet的构造函数仅声明一个参数。这让我很困惑,我怀疑我错过了一些东西,或者使用了框架的版本而不是核心,或者其他东西。
Pet*_*ala 10
正如我所看到的(它是 的基类)Name属性的最大优点是您可以区分方法重载:HttpMethodAttributeHttpGetAttribute
[HttpGet(Name="ById"]
public IActionResult GetBy(int id)
{
}
[HttpGet(Name="ByExternalId"]
public IActionResult GetBy(Guid id)
{
}
Run Code Online (Sandbox Code Playgroud)
更新#1:我修改了答案
上面的示例代码将产生一个AmbiguousMatchException,其中表示Template已为不同的操作注册了相同的操作。
我整理了另一个示例并使用以下RouteDebugger来获得见解。在该Configure方法中,我调用了该app.UseRouteDebugger()方法,以便能够在/route-debugger url 下查看 json 格式的注册路由。
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
[HttpGet()]
public IActionResult GetA(string a)
{
return Ok(nameof(GetA));
}
[HttpGet(template: "GetB")]
public IActionResult GetB(string b)
{
return Ok(nameof(GetB));
}
[HttpGet(template: "GetC", Name= "GetD")]
public IActionResult GetD(string d, string e)
{
return CreatedAtRoute(routeName:"GetC", routeValues: new { c = "v"}, value: null);
}
[HttpGet(template: "GetC/{c}", Name = "GetC")]
public IActionResult GetC(string c)
{
return Ok(nameof(GetC));
}
}
Run Code Online (Sandbox Code Playgroud)
路由表如下所示:
[HttpGet(Name="ById"]
public IActionResult GetBy(int id)
{
}
[HttpGet(Name="ByExternalId"]
public IActionResult GetBy(Guid id)
{
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,发生了以下情况:
Template因为没有指定,所以它暴露在控制器路由下。Name,因此您无法通过其内部的名称ActionLink或CreatedAtRoute等来引用该路线。api/test/getb,因为控制器的属性和操作的Template属性是组合在一起的。Name,因此您无法通过其内部的名称ActionLink或CreatedAtRoute等来引用该路线。api/test/getc/{c},因为控制器的属性和操作的Template属性是组合在一起的。该c参数可以接受任何值。如果未提供,则会GetD被调用,因为它是先注册的。Name( ),因此您可以通过其内部的名称或等GetC来引用该路线。就像我们在里面所做的那样ActionLinkCreatedAtRouteGetDapi/test/getc,因为控制器的属性和操作的Template属性是组合在一起的。因为它是先前GetC方法的路由注册的,所以如果没有提供进一步的路径,它将被调用。Name(GetD)。在 中,CreatedAtRoute我们GetC通过其名称而不是通过其路线来指代。如果我们将名称替换为,GetC那么它将在运行时抛出以下异常:InvalidOperationException:属性路由信息发生以下错误:
错误1:同名“GetC”的属性路由必须具有相同的模板:操作:“Controllers.TestController.GetD()”-模板:“api/Test/GetC”操作:“Controllers.TestController.GetC()” - 模板:'api/Test/GetC/{c}
Template它将在运行时抛出一个异常。AmbiguousMatchException(所以,其他路线也可以正常工作)Name它将在运行时抛出一个异常。InvalidOperationException(所以其他路线不行)Name提供了在不知道确切信息的情况下轻松引用它们的能力Template。这种分离使我们能够在不影响引用链接的情况下进行更改Template。名称是路线名称,与模板不同。请参阅文档页面。
文档指出:
路由名称可用于根据特定路由生成 URL。路线名称:
- 对路由的URL匹配行为没有影响。
- 仅用于 URL 生成。
路由名称在应用程序范围内必须是唯一的。
您可以使用该名称为命名路由生成 URL IUrlHelper。例如,如果您将路线命名为“Konrad”,则可以生成如下链接:
string url = urlHelper.Link("Konrad", new { id = 5, query = "test" });
Run Code Online (Sandbox Code Playgroud)
其中 id 和 query 是路由参数。
顺便说一句,您在文档中遇到的问题HttpGet是Attribute。属性语法允许您在任何位置构造函数值之后按名称指定属性的属性值。
考虑以下属性,您可以看到构造函数接受int a,但还有一个字符串属性:B。
public class TestAttribute : System.Attribute
{
public TestAttribute(int a)
{
}
public string B {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
要使用此类属性,您可以通过以下方式应用它:
[TestAttribute(5)] // B is null
[TestAttribute(5, B = "hello")] // B is "hello"
Run Code Online (Sandbox Code Playgroud)
或者简单地如下Test:
[Test(5)] // B is null
[Test(5, B = "hello")] // B is "hello"
Run Code Online (Sandbox Code Playgroud)
它说它们可用于根据特定路由生成 URL。我认为我不明白它的意思(尽管理解这些词本身)。请详细说明
这是我的两分钱:
在设计适当的 API 时,成熟度模型的第 3 级讨论了 HATEOAS 约束(超媒体作为应用程序状态的传输引擎)。有关它的更多信息可以在: Rest API 的成熟度模型中找到
为了遍历资源并了解该资源可用的操作,我们生成该资源的链接。
链接的生成是在 URLHelper 库的帮助下完成的,它接受一个名称参数来定义链接。我们在 URLHelper 库中关联的名称是使用属性 Name 参数为 HTTP GET/POST/PUT 等操作定义的名称。
简单来说,它是您的路线的标识符。
聚苯乙烯
可以在 github 上找到使用 HATEOAS 的 Web api 的完整工作示例: