我正在升级一个自定义解决方案,我可以在其中动态注册和注销 Web Api 控制器以使用新的属性路由机制。但是,最近对 RTM 的更新似乎破坏了我的解决方案。
我的解决方案公开了几个用于管理目的的 Web Api 控制器。这些是使用新的 HttpConfigurationExtensions.MapHttpAttributeRoutes 方法调用注册的。
该解决方案还允许 Web Api 控制器托管在第三方程序集中并动态注册。在这个阶段,一旦加载了第三方控制器,再次调用 HttpConfigurationExtensions.MapHttAttributeRoutes 将引发异常。因此,我的解决方案使用反射来检查 RoutePrefix 和 Route 属性,并在 HttpConfiguration 对象上注册相应的路由。
不幸的是,调用 Web Api 会导致以下错误:
“未找到与请求 URI 匹配的 HTTP 资源”。
这是我想使用的简单控制器:
[RoutePrefix("api/ze")]
public sealed class ZeController : ApiController
{
[HttpGet]
[Route("one")]
public string GetOne()
{
return "One";
}
[HttpGet]
[Route("two")]
public string GetTwo()
{
return "Two";
}
[HttpPost]
[Route("one")]
public string SetOne(string value)
{
return String.Empty;
}
}
这是我尝试的第一个解决方案:
configuration.Routes.MapHttpRoute("ZeApi", "api/ze/{action}");
这是我尝试的第二个解决方案:
var type = typeof(ZeController);
var routeMembers = type.GetMethods().Where(m => m.IsPublic);
foreach (MethodInfo method in routeMembers)
{
var routeAttribute = method.GetCustomAttributes(false).OfType<RouteAttribute>().FirstOrDefault();
if (routeAttribute != null)
{
string controllerName = type.Name.Substring(0, type.Name.LastIndexOf("Controller"));
string routeTemplate = string.Join("/", "api/Ze", routeAttribute.Template);
configuration.Routes.MapHttpRoute(method.Name, routeTemplate);
}
}
我还尝试了第三种解决方案,我创建了实现 IHttpRoute 的自定义类,并尝试将它们注册到配置中,但无济于事。
是否可以根据新路由属性中包含的信息使用传统样式的路由映射?
更新
我已经在 Web 应用程序中安装了我的控制器,以便使用Web Api Route Debugger对路由选择过程进行故障排除。这是屏幕截图的结果:
如您所见,似乎选择了正确的操作,但我仍然收到 404 错误。
更新2
经过进一步分析,以及下面 Kiran Challa 的评论,Web Api 的设计似乎阻止了属性路由和常规路由的混合,而我想要做的事情是不可能使用这种方法的。
我创建了一个自定义属性 [RouteEx],它与 Web Api [Route] 属性的用途相同,现在我的代码可以完美运行。
我想,由于使用传统的属性路由是不可能的,所以关于这个问题的答案都不能合法地被认为是有效的。所以我还没有提名答案。