ASP.Net WebAPI区域支持

时间:2012-06-17 19:19:38

标签: asp.net-mvc asp.net-web-api

我正在尝试向我的asp.net 4 RC网站添加一些WebAPI支持,并希望将其放入某个区域。我看到有人设法在测试版上运行(here),但说实话,我不知道我在RC中做了什么。

有没有人设法为WebAPI的RC添加区域支持?

5 个答案:

答案 0 :(得分:57)

您可以将Api控制器放在任何您喜欢的文件夹中,您不需要像为MVC那样创建区域。我通常做的是在MVC站点的“Controllers”文件夹中创建一个子文件夹“Api”。只需为您的Api控制器注册路线即可。

答案 1 :(得分:21)

支持网址API网址中的区域

您只需注册Web API路由。

但是这条路线必须在其他路线之前注册。如果没有,那么对Web API的请求将被错误地处理,就好像它们是MVC动作一样。

当您使用区域时,您必须考虑到区域路线的注册通常在注册非区域路线之前完成。即,在Global.asax Application_Start中,您按以下顺序拥有这些代码行:

AreaRegistration.RegisterAllAreas();
// ...
RouteConfig.RegisterRoutes(RouteTable.Routes);

第一个方法调用将调用每个找到的RegisterArea类的xxxAreaRegistration方法。而且,在这个配置中,你通常会有这样的东西:

context.MapRoute(
    "AreaName_default",
    "AreaName/{controller}/{action}/{id}",
    new { action = "Index", id = UrlParameter.Optional }
);

如果您希望在此区域内安装Web API控制器,则必须在此之前添加Web API路由,如下所示:

context.Routes.MapHttpRoute("AreaName_WebApiRoute",
    "AreaName/Api/{controller}/{id}",
    new { id = RouteParameter.Optional });

在这种情况下,我假设你想使用这样的网址调用你的API控制器:/AreaName/Api/ControllerName/Id

我通常将Web API控制器存储在区域文件夹内的Api文件夹中,但是放在哪里并不重要。考虑到API控制器可以在任何地方找到它们,如果你在不同的区域使用相同的名称,你会遇到冲突:它们是通过类名找到的,而不是完全限定的(命名空间)名称。

简而言之:对区域没有真正的支持,但是你可以将它们包含在区域内的自己的文件夹中,并使它们在URL上看起来像是区域内的MVC控制器。

支持路线名称空间

如果您希望在不同区域中使用相同名称的Web API控制器,该怎么办?如果您真的想要为Web API控制器提供真正的支持,您必须实现并注册自定义IHttpControllerSelector

您有一个很好的解释和示例实现:ASP.NET Web API: Using Namespaces to Version Web APIs

此示例使用名称空间进行版本控制,但可以稍微修改代码以支持区域名称空间。

答案 2 :(得分:13)

ASP.NET MVC 4不支持区域中的WebAPI。

可以扩展DefaultHttpControllerSelector来执行此操作,但您应该仔细阅读这篇优秀(简短)的文章:ASP.NET MVC 4 RC: Getting WebApi and Areas to play nicely。它很棒。

我已成功使用便携式区域(MVCContrib)测试此解决方案。 基本上,你必须:

  • 在PA项目中放置扩展方法“AreaRegistrationContextExtensions”(从PortableAreaRegistration.RegisterArea()方法中需要):您可以将静态类复制到PA项目中,但我建议将其放入共享项目中。
  • 将类“AreaHttpControllerSelector”(继承自DefaultHttpControllerSelector)添加到主机项目中。
  • 将以下行添加到Global.asax App_Start():

    GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),new AreaHttpControllerSelector(GlobalConfiguration.Configuration));

AreaHttpControllerSelector的实现有一点需要注意:区域名称必须与ApiController的命名空间相对应。例如,这是我的PortableAreaRegistration类:

namespace PortableAreasSample.MembershipArea
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using MvcContrib.PortableAreas;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Routing;

    public class MembershipRegistration : PortableAreaRegistration
    {
        public override void RegisterArea(System.Web.Mvc.AreaRegistrationContext context, IApplicationBus bus)
        {
            // GET /MembershipArea/GetAllUsers
            context.MapHttpRoute("MembershipApi",
                AreaName + "/{controller}/{id}",
                new { area=AreaName, controller = "GetAllUsers", id = RouteParameter.Optional });
        }

        public override string AreaName
        {
            get { return "MembershipArea"; }
        }
    }
}

答案 3 :(得分:4)

确保在默认路由之前注册API路由,否则默认路由将贪婪地捕获所有内容!

答案 4 :(得分:1)

只是为了完成,存在以下属性,这可以帮助人们摆脱绑定(谁不会遵循上面的eric建议......)

[Route ("api/interesting/{id?}")]
[RoutePrefix("api/interesting")]

http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2