37

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

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

4

5 回答 5

62

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

于 2012-06-18T07:18:53.603 回答
24

Web API URL 中的支持区域

您只需注册 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 });

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

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

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

支持路由命名空间

如果您想在不同的区域拥有相同名称的 Web API 控制器怎么办?如果您真的想为 Web API 控制器的区域提供真正的支持,您必须实现并注册一个自定义IHttpControllerSelector

你有一个很好的解释,这里有一个示例实现:ASP.NET Web API: Using Namespaces to Version Web APIs

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

于 2014-02-20T15:16:29.597 回答
13

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

可以扩展DefaultHttpControllerSelector来执行此操作,但您应该仔细阅读这篇出色的(且简短的)文章:ASP.NET MVC 4 RC:让 WebApi 和 Areas 玩得很好。它工作得很好。

我已经用便携式区域(MVCContrib)成功地测试了这个解决方案。基本上,您必须:

  • 将扩展方法“AreaRegistrationContextExtensions”放在 PA 项目中(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"; }
        }
    }
}
于 2012-07-17T17:41:33.253 回答
4

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

于 2012-06-18T18:46:41.543 回答
2

只是为了完成,存在以下属性,这可以帮助人们摆脱束缚(谁不会遵循上面 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

于 2013-10-29T15:24:18.797 回答