ASP.Net WebAPI区域支持

Jon*_*tes 34 asp.net-mvc asp.net-web-api

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

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

fre*_*nky 58

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

  • 谢谢.事实证明我的工作正常,因为我在默认路由后注册了我的/ api/route,这是捕获所有api调用 (3认同)

Jot*_*aBe 22

支持Web API URL中的区域

您只需注册Web API路由即可.

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

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

AreaRegistration.RegisterAllAreas();
// ...
RouteConfig.RegisterRoutes(RouteTable.Routes);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

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

支持路由名称空间

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

您有一个很好的解释和示例实现:ASP.NET Web API:使用命名空间到版本Web API

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


Eri*_*dil 13

ASP.NET MVC 4不支持Area中的WebAPI.

可以扩展DefaultHttpControllerSelector这样做,但是你应该仔细阅读这篇优秀(和简短)的文章:ASP.NET MVC 4 RC:让WebApi和Areas能够很好地发挥作用.它很棒.

我已经用便携式区域(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"; }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)