【问题标题】:WebAPI 2 Attribute routing with areas not workingWebAPI 2 属性路由与区域不工作
【发布时间】:2015-09-09 13:43:33
【问题描述】:

我无法让 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()打过电话吗?
  • 是的。添加到原始问题。
  • 看到这个 [System.Web.Mvc.RequireHttps],它是针对 MVC 而不是 WebAPI。如果你删除它会发生什么?
  • 没有变化。决定离开区域,因为 webapi 2 不支持路由到区域:asp.net/web-api/overview/web-api-routing-and-actions/… - 请参阅 Mike 的第一条评论。

标签: c# rest asp.net-web-api asp.net-mvc-routing asp.net-web-api2


【解决方案1】:

尝试在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);

顺序很重要(如果我用 WebApiConfig 反转 areaRegistration => WebAPI 2 attributeRouting 将不起作用

【讨论】:

    【解决方案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 }
            );
        }
    }
    

    【讨论】:

      【解决方案3】:

      区域功能在 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 中的可用性即可

      【讨论】:

      • 这是一个很好的答案,可以解决关于 web api 区域/命名空间/等的无数问题。该解决方案允许您将控制器放置在您喜欢的任何地方并创建可破解的 api。唯一需要注意的是,您不能有重复的控制器名称,因为 web api 在创建路由字典时不使用完整的命名空间。
      【解决方案4】:

      该项目从一开始就是 MVC 项目吗?那么我认为您应该删除创建区域时创建的“ApiAreaRegistration.cs”文件。它位于您的 Api 区域的根目录中,并且会与您的属性路由冲突,因为它会在找到您的之前与“api/{controller}/{action}/{id}”之类的 MVC(不是 WebApi)路由匹配具体路线。

      希望对你有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-25
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 2013-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多