我正在升级自定义解决方案,我可以动态注册和取消注册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错误。
UPDATE2
经过进一步分析,根据Kiran Challa在下面的评论,似乎Web Api的设计阻止了混合属性路由和传统路由,并且使用这种方法我不想做的事情。
我创建了一个自定义属性[RouteEx],其功能与Web Api [Route]属性相同,现在我的代码运行完美。
我想,因为使用传统的属性路由是不可能的,所以这个问题的答案都不能合法地被认为是有效的。所以我还没有提名答案。
答案 0 :(得分:0)
不应要求您使用反射并自行检查基于属性路由的属性。属性路由使用现有的Web API功能来获取要扫描的控制器列表。
问题:在切换到属性路由之前,如何加载具有该属性的这些程序集 控制器?
如果您是通过IAssembliesResolver
服务执行此操作,那么此解决方案即使使用属性路由也应该有效,您不需要做任何额外的事情。
关于更新:您是否正在呼叫MapHttpAttributeRoutes
?