【问题标题】:ASP.NET Core LinkGenerator and compile time checksASP.NET Core LinkGenerator 和编译时间检查
【发布时间】:2021-02-24 09:16:51
【问题描述】:

ASP.NET Core 有一个有用的类 LinkGenerator,它可以从控制器方法名称生成链接。 但是,这种行为似乎很脆弱,因为它依赖于仅在运行时检查的基于字符串的合约。
如果我更改一个控制器方法名称或一个方法参数名称,程序将表现不佳。 例如:

string url = _linkGenerator.GetPathByAction
(
    HttpContext,
    action: "GetJobStatus",
    values: new { jobId = jobId }
).ToString();

您知道 ASP.NET Core 中强制执行一些编译时间或启动时间检查的功能吗?
比如我想写:

string url = _linkGenerator.GetPathByAction
(
    HttpContext,
    actionAndValues: () => this.GetJobStatus(jobId), // compile time check (method exists and arguments are compatible)
    action: this.GetJobStatus, // at least this: compile time check (method exists)
).ToString();

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    为确保方法存在,可以使用nameof()操作符:

    string url = _linkGenerator.GetPathByAction
    (
        HttpContext,
        action: nameof(GetJobStatus),
        values: new { jobId = jobId }
    ).ToString();
    

    据我所知,在编译时无法确保这些值是正确的。我不确定这是否会对您有所帮助,但有一种方法可以在运行时检索操作描述符。您也许可以在调用链接生成器之前使用它来检查参数。

    类似这样的:

    public MyController(IActionDescriptorCollectionProvider actionDescriptorCollection)
    {
        var actionDescriptor = actionDescriptorCollection
            .ActionDescriptors
            .Items
            .OfType<ControllerActionDescriptor>()
            .SingleOrDefault(_ => 
                _.ControllerName == nameof(MyController).Replace("Controller", string.Empty) &&
                _.MethodInfo.Name == nameof(GetJobStatus)
                );
    
        var parameters = actionDescriptor
            .Parameters
            .Where(_ => _.BindingInfo.BindingSource != BindingSource.Services) // filter parameters not coming from the route
            .ToList();
    
        // do something with the parameters
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-12
      • 2020-01-07
      • 1970-01-01
      • 2015-02-11
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多