将路由属性与任意字符串组合
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/1
,route2
可以转到 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()));
}
我正在尝试在我的网关上创建一个控制器,它除了将请求代理到另一个 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/1
,route2
可以转到 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()));
}