【问题标题】:Cannot get LinkGenerator to create a path to API action无法让 LinkGenerator 创建 API 操作的路径
【发布时间】:2019-07-28 09:59:18
【问题描述】:

我正在尝试从服务内部(控制器外部)创建到 API 端点的链接。

这是控制器及其基类。我在 ASP.NET Core 中使用 API 版本控制和区域。

[ApiController]
[Area("api")]
[Route("[area]/[controller]")]
public abstract class APIControllerBase : ControllerBase
{

}

[ApiVersion("1.0")]
public class WidgetsController : APIControllerBase
{
    [HttpGet("{id}"]
    [Produces("application/json")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<Widget>> Get(Guid id)
    {
        // Action...
    }
}

API 版本配置:

services.AddApiVersioning(options =>
{
    options.ApiVersionReader = ApiVersionReader.Combine(
        new QueryStringApiVersionReader
        {
            ParameterNames = { "api-version", "apiVersion" }
        },
        new HeaderApiVersionReader
        {
            HeaderNames = { "api-version", "apiVersion" }
        });
});

我实际尝试使用 LinkGenerator 的地方:

_linkGenerator.GetPathByAction(
    _accessor.HttpContext,
    action: "Get",
    controller: "Widgets",
    values: new
    {
        id = widget.Id,
        apiVersion = "1.0"
    }
)

我已经尝试了 LinkGenerator 的各种变体。我已经使用了 HttpContext 重载,我已经使用了没有它的重载,我已经包含了 apiVersion 参数并省略了它,我已经从控制器中完全删除了[ApiVersion]。一切都会回来null。如果我路由到像 GetPathByAction("Index", "Home") 这样的普通 MVC 控制器,我会得到一个我应该得到的 URL,所以我认为它一定与我的 API 区域或版本设置有关。

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc url-routing


    【解决方案1】:

    如果它对其他人有帮助,我遇到了一个与此非常相似的问题,但该操作被命名为 GetAsync,事实证明您无法通过其全名“GetAsync”引用该操作,您必须在没有后缀所以只是“获取”。

    【讨论】:

    • 谢谢。这正是我遇到的问题。这些隐含的命名规则确实弊大于利。
    【解决方案2】:

    您没有指定区域:

    _linkGenerator.GetPathByAction(
        _accessor.HttpContext,
        action: "Get",
        controller: "Widgets",
        values: new
        {
            area = "api",
            id = widget.Id,
            apiVersion = "1.0"
        }
    )
    

    【讨论】:

    • 那行得通。我没有考虑将区域作为参数,并认为路由器会自行映射到它。
    • 不。没有区域被假定为没有区域,因此它不会明确匹配区域内的任何内容。在处理区域时,其工作方式与 Html.Action 之类的相同。
    • 有道理。我最初认为 LinkGenerator 方法会有一个area 参数,因为我倾向于认为区域与控制器和操作处于同一层次结构中。
    • 是的。这是一个普遍的假设。我认为这源于两件事:首先,很多都建立在来自 ASP.NET MVC 的约定上(例如,Html.Action API 保持不变)并且区域最初不是 ASP.NET MVC 的一部分,但是而是后来添加的。其次,最终,方法签名开始因参数而变得臃肿。为 area 添加一个参数不仅会增加一个参数,而且还需要覆盖签名的指数增加。鉴于它适用于路由值参数,因此确实没有必要这样做。
    • 有趣的是,动作和控制器在技术上可以通过路由值参数指定,只是这样做并不典型,因为它们有特定的参数,并且至少在动作的情况下,没有可用的签名,你不必至少通过一个动作。
    猜你喜欢
    • 2019-09-04
    • 2020-03-21
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 2018-12-10
    • 2023-04-04
    • 1970-01-01
    • 2018-08-09
    相关资源
    最近更新 更多