WebAPI 2区域属性路由不起作用

4

我在使用WEBAPI 2的属性路由时遇到了问题。我需要实现的路由方案是/api/{product}/{controller}/{id-optional},例如/api/Vision/IdCard。这些控制器位于一个区域内,并按照以下方式设置:

namespace DataServices.Controllers.Vision
{
     [RoutePrefix("api/vision")]
        public class IdCardController : BaseApiController
        {
            [System.Web.Mvc.RequireHttps]
            [Route("idcard")]
            public IdCardViewModel Get(HttpRequestMessage request)
            {...}

每当我尝试调用该接口时,都会收到一个404错误代码。我已经在代码中包含了命名空间,因为该区域位于自己的命名空间下,但是这样做仍然无法解决问题。请问WEBAPI属性路由支持区域吗?

编辑:WebApiConfig如下:

 config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

你是否调用了MapHttpAttributeRoutes()函数? - Hamid Pourjam
是的。已添加到原始问题中。 - Bill Martin
看到这个[System.Web.Mvc.RequireHttps],它是针对MVC而不是WebAPI的。如果将其删除会发生什么? - hazjack
决定撤离该区域,因为在WebAPI 2中似乎不支持到达区域的路由:http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2——请参见Mike的第一条评论。 - Bill Martin
4个回答

2
您需要从GlobalConfiguration对象中获取HttpConfiguration实例,并在AreaRegistration.cs的RegisterArea方法内调用MapHttpAttributeRoutes()方法。
    public override void RegisterArea(AreaRegistrationContext context) 
    {
        GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

        //... omitted code  
    }

这必须针对每个区域进行操作。 最后,您必须在“WebApiConfig”中删除“config.MapHttpAttributes()”方法,否则您将获得重复异常。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();

        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));


        // Web API routes
        //config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

1

在Asp.Net Web API项目中,区域功能不可用,并且使用基于命名空间的控制器等自定义方式更难以维护。我已经检查了许多基于命名空间的控制器和路由问题,例如单个操作方法可以通过基于命名空间的路由和默认路由访问。因此,自定义实现不能满足我们的要求。

为了解决这个问题,我们可以使用简单的方式来管理控制器路由,如下:

      //Remove default routing registration      
      /*config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );*/

只使用基于属性的路由,比如:

[RoutePrefix("api/user/home")]
public class UserHomeController : ApiController
{
     [Route]
     public string Get()
     {
       return "Test user GET";
     }
}

对于不同的区域/模块控制器

[RoutePrefix("api/admin/home")]
public class AdminHomeController : ApiController
{
     [Route]
     public string Get()
     {
       return "Test admin GET";
     }
}

采用这种方法的优点包括:

  • 不需要像基于命名空间的区域、自定义路由处理程序等自定义逻辑,因此这是更好的编码方式。
  • 只需在操作中添加属性 [Route] 就可以在 API 中使用。

1
这是关于Web API区域/命名空间等问题的众多问题的一个好答案。此解决方案允许您将控制器放置在任何位置,并创建可hack的API。唯一的注意事项是,您不能有重复的控制器名称,因为Web API在创建路由字典时不使用完整的命名空间。 - trevorc

1
如果项目从一开始就是MVC项目,那么我认为您应该删除创建区域时创建的“ApiAreaRegistration.cs”文件。它位于您的Api区域的根目录中,并且会与您的属性路由产生冲突,因为它将在找到特定路由之前匹配一个MVC(而不是WebApi)路线,例如“api/{controller}/{action}/{id}”。希望对你有帮助!

0

尝试在Application_Start中玩弄初始化顺序。

//Config WebAPI(2) where you call config.MapHttpAttributeRoutes();
  • GlobalConfiguration.Configure(WebApiConfig.Register);

  • AreaRegistration.RegisterAllAreas();

  • FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  • RouteConfig.RegisterRoutes(RouteTable.Routes);
  • BundleConfig.RegisterBundles(BundleTable.Bundles);

顺序非常重要(如果我将areaRegistration与WebApiConfig反转,则WebAPI 2属性路由将无法工作)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接