【发布时间】:2015-03-18 05:30:52
【问题描述】:
我有一个网站,它在不同的路径上公开了多个 API,每个 API 都由特定于应用程序部分的控制器处理,例如 example.com/Api/Controller/Action?param1=stuff,其中控制器发生变化,但操作保持相当一致。
我有几个调用这些 API 的集成设备。问题是这些集成设备不容易更改,我希望它们指向的特定控制器将来需要更改。
我的计划是使用虚拟重定向之类的东西,所有设备都会调用一个固定的 URL,例如 example.com/Api/VRedirect/{deviceId}/MethodName?param1=test
根据deviceId 的值,实际使用的控制器会发生变化(基于某些数据库查找逻辑)。
例如,如果deviceId 1234 被查找并返回“示例”,则调用example.com/Api/VRedirect/1234/Test?param1=test 将等同于直接调用example.com/Api/Example/Test?param1=test。
到目前为止,我还没有找到正确实现这一点的方法,我接近的唯一方法是使用自定义路由:
app.UseMvc(routes => {
routes.MapRoute(
name: "RedirectRoute",
template: "Api/VRedirect/{deviceId}/{*subAction}",
defaults: new { controller = "BaseApi", action = "VRedirect"});
);
带有重定向操作:
public IActionResult VRedirect(string deviceId, string subAction) {
string controllerName = "Example"; // Database lookup based off deviceId
return Redirect(string.Format("/Api/{0}/{1}", controllerName, subAction));
}
这部分适用于 GET 请求,但根本不适用于 POST,因为它会丢弃所有 POST 数据。
有没有办法实现这样的事情?我怀疑我可能需要编写一个自定义路由器,但我不确定从哪里开始。
更新: 通过简单地在循环中为每个设备添加一个路由,我已经设法使用默认路由器完成所需的行为:
app.UseMvc(routes => {
Dictionary<string, string> deviceRouteAssignments = new Dictionary<string, string>();
// TODO: Get all these assignments from a database
deviceRouteAssignments.Add("12345", "ExampleControllerName");
foreach (var thisAssignment in deviceRouteAssignments) {
routes.MapRoute(
name: "DeviceRouteAssignment_" + thisAssignment.Key,
template: "Api/VRedirect/" + thisAssignment.Key + "/{action}",
defaults: new { controller = thisAssignment.Value });
}
}
}
但是,这有一些明显的限制,例如仅在应用程序启动时更新路由。大量路由的性能下降可能是一个问题,但是我测试了 10,000 条路由,没有发现任何明显的减速。
【问题讨论】:
标签: c# asp.net asp.net-mvc routes asp.net-core