2

我正在升级一个自定义解决方案,我可以在其中动态注册和注销 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对路由选择过程进行故障排除。这是屏幕截图的结果:

路由调试器中的 Web Api 路由选择

如您所见,似乎选择了正确的操作,但我仍然收到 404 错误。

更新2

经过进一步分析,以及下面 Kiran Challa 的评论,Web Api 的设计似乎阻止了属性路由和常规路由的混合,而我想要做的事情是不可能使用这种方法的。

我创建了一个自定义属性 [RouteEx],它与 Web Api [Route] 属性的用途相同,现在我的代码可以完美运行。

我想,由于使用传统的属性路由是不可能的,所以关于这个问题的答案都不能合法地被认为是有效的。所以我还没有提名答案。

4

1 回答 1

0

您不应该被要求自己使用反射和检查基于属性路由的属性。属性路由使用现有的 Web API 功能来获取要扫描的控制器列表。

问题:在切换到属性路由之前,您是如何加载这些具有控制器的程序集的?

如果您是通过IAssembliesResolver服务执行此操作,那么即使使用属性路由,此解决方案也应该可以工作,并且您不需要做任何额外的事情。

关于您的更新:您在打电话MapHttpAttributeRoutes吗?

于 2013-10-22T21:46:15.890 回答