将路由属性与任意字符串组合

Combine Route Attribute With Arbitrary String

我正在尝试在我的网关上创建一个控制器,它除了将请求代理到另一个 API 之外几乎什么都不做。 (它做了一些其他非常基本的准备工作,但这有点超出了本文的范围,所以我把它排除在外了)。这之前由大约 20 个控制器处理,它们都做同样的事情,所以我试图简化事情。

[Route("api/reporting/route1")]
[Route("api/reporting/route2")]
public class TestController : Controller
{
    [HttpPost("{clientId:int")]
    public async Task<ActionResult<MemoryStream>> GetReport(int clientId, [FromBody] object requestBody)
    {
            var report     = await ReportingClient.DownloadReport(/*HERE*/, requestBody);
            return File(report, "application/pdf");                       
    }
}

目的地完全由到达此控制器的路线决定。

route1 可以转到 api/reporting/test/1route2 可以转到 api/test/2

已经存在的东西并不像我想要的那样一致,但让它们都一致超出了我的范围。

因此,我希望能够使用将 Route 与任意 Target 字符串组合的属性来装饰我的控制器。

像这样:

[ProxyRoute("api/reporting/route1", "api/reporting/test/1")]
[ProxyRoute("api/reporting/route2", "api/test/2")]
public class TestController : Controller
{
    [HttpPost("{clientId:int")]
    public async Task<ActionResult<MemoryStream>> GetReport(int clientId, [FromBody] object requestBody)
    {
            var report     = await ReportingClient.DownloadReport(Target, requestBody);
            return File(report, "application/pdf");                       
    }
}

当然,我可以在我的 class 中包含一个静态只读字典来实现这一点,但我觉得那样比较麻烦,所以如果可以的话我想用一个属性来做到这一点。

我该如何实现?

所以我实际上解决了这个...我想我在脑海中把它复杂化了。我所需要的只是继承 RouteAttribute 本身,然后将我的额外字符串添加为 public 属性:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
    protected class ReportingProxyRouteAttribute : RouteAttribute
    {
        public string Destination    { get; }
        public ReportingProxyRouteAttribute(string template, string destination) : base(template)
        {
           Destination    = destination;
        }
    } 

然后我可以自己得到额外的字符串:

    private ReportingProxyRouteAttribute GetRouteForRequest()
    {
       var possibleRoutes = Attribute.GetCustomAttributes(GetType(), typeof(ReportingProxyRouteAttribute)).Cast<ReportingProxyRouteAttribute>();
       return possibleRoutes.First(r => Request.Path.ToString().ToLowerInvariant().Contains(r.Template.ToLowerInvariant()));
    }