c# - ASP.NET Core (MVC 6) 中的路由消歧

标签 c# rest asp.net-web-api asp.net-core swagger

当 ASP.NET Core 遇到命名不明确的路由时,它会变得惰性。也就是说,应用程序将运行而不会抛出异常,但是它将无法处理任何 Controller 上的任何请求。调用客户端收到 500 个响应。

我将展示我是如何陷入这种困境的,并且我希望得到有关如何解决它的建议。

我有一个看起来像这样的 Controller :

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]
public class AddressesController : Controller
{

    [HttpGet("{aid}", Name = "PostalLink")]
    public async Task<IActionResult> GetAddress(Guid id, Guid aid)
    {
        //...implementation is irrelevant for this question.
    }

    [HttpPost]
    [SwaggerResponseRemoveDefaults]
    [SwaggerResponse(HttpStatusCode.Created, Type = typeof(PostalRecord))]
    public async Task<IActionResult> CreateAddress(Guid id, [FromBody] PostalAddress address)
    {
        address.ID = Guid.NewGuid();
        await createAddress.Handle(address);

        return CreatedAtRoute("PostalLink", new { id = id, aid = address.ID });
    }

为什么 Controller 上有两个路由前缀?因为它符合我的微服务(和 Swagger 文档)策略。然而,在此示例中,ASP.NET Core 不知道如何解析路由名称“PostalLink”,因为它隐式绑定(bind)到两个前缀:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]

我可以简单地通过更改 HttpGet 来解决这个问题,而不是这样:

    [HttpGet("{aid}", Name = "PostalLink")]

我有这个:

    [HttpGet("{aid}")] //the route is no longer "named"

不幸的是,删除路由名称对我来说不是一个真正的选择。

解决此问题的规定方法是什么?

以下是我正在考虑的一些选项。

可能性 #1

理论上,ASP.NET 可以简单地自行“解决”。例如,如果当前请求解析为包含单词“Subscribers”的路由,则“PostalLink”名称应引用该路由。这样看来,也许我的代码暴露了 ASP.NET Core 中的错误、缺陷或疏忽。

可能性#2

我可以像这样将两个前缀路由折叠成一个路由:

[Route("api/{parent}/{id}/[controller]")]

这行得通,但它破坏了我的 REST 文档策略。我正在使用 Swashbuckle 发布端点元数据。我希望我的 API 的用户明确看到我的“地址”API 服务于“订阅者”或“组织”。当我有两个显式路由前缀时,Swagger 文档可以正常工作(并且我可以正确验证客户端使用的 URI)。

可能性 #3

我可以像这样简单地覆盖两个前缀:

    [HttpGet("~/api/Subscribers/{id}/Addresses/{aid}", Name = "SubscriberLink")]
    [HttpGet("~/api/Organizations/{id}/Addresses/{aid}", Name = "OrganizationLink")]
    public async Task<IActionResult> GetAddress(Guid id, Guid aid)
    {
        //...implementation is irrelevant for this question.
    }

现在我的文档和路由验证有效,但我的实现被迫检查使用哪条路由到达端点。这是非常可行的,但非常烦人。

可能性 #4

也许没有基于属性的路由,有一种更具表现力的方法来处理这个问题?如果是,请分享!

详情

我的project.json配置如下:

"frameworks": {
  "dnx46": { }
},

我使用的是 DNX SDK 版本 1.0.0-rc1-update1。另外,我发布了一个 related SO question对于那些想要更多了解我正在尝试做的事情的人。

最佳答案

如果所有操作的路由名称都相同,为什么不直接在 Controller 上指定它们?

[Route("api/Subscribers/{id}/[controller]", Name = "SubscriberLink")]
[Route("api/Organizations/{id}/[controller]", Name = "OrganizationLink")]
public class AddressesController : Controller
{

    [HttpGet("{aid}")]
    public async Task<IActionResult> GetAddress(Guid id, Guid aid)
    {
        //...implementation is irrelevant for this question.
    }
}

关于c# - ASP.NET Core (MVC 6) 中的路由消歧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36522617/

相关文章:

c# - 有什么方法可以对 C# 中的属性执行某种空合并?

c# - 调试返回值

web-services - 使用 REST API 和 SugarCRM 将目标添加到目标列表

c# - Web API 2 REST 服务高级数据过滤

asp.net-mvc - 路由不起作用 - Webapi ASP.NET

c# - 有没有更好的方法在ActionFilterAttribute中获取cookie值?

security - 具有同源策略和 OAuth 的 REST API 身份验证

c# - 无法从 UnityEngine.Vector3 转换为 System.Collections.Generic.List<UnityEngine.Vector3>

c# - 访问SQL Server数据库的登录表单错误

java - 使用 REST WS 处理附件