asp.net-mvc ASP.Net WebAPI 区域支持

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11074117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:02:52  来源:igfitidea点击:

ASP.Net WebAPI area support

asp.net-mvcasp.net-web-api

提问by Jon Bates

I am trying to add some WebAPI support to my asp.net 4 RC site, and wish to put it into an area. I have seen that someone managed to get this running on the beta (here) , but to be honest, have no idea what I am doing in the RC.

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

Has anybody managed to add area support to the RC of WebAPI?

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

回答by frennky

You can put Api controllers in any folder you like, you don't need to create an Area like you did for MVC. What I usually do is create a subfolder 'Api' inside 'Controllers' folder of MVC site. Just register routes for your Api controllers and it will work.

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

回答by JotaBe

Supporting areas in the web API URLs

Web API URL 中的支持区域

You simply have to register the Web API route.

您只需注册 Web API 路由。

But this route must be registered before the other routes. If not, the requests to the web API will be mistakenly handled as if they were an MVC action.

但是这条路由必须在其他路由之前注册。否则,对 Web API 的请求将被错误地处理,就好像它们是 MVC 操作一样。

When you're using areas, you must take into account that the registration for the areas routes is usually done before the registration of the non-area routes. I.e, in Global.asax Application_Startyou have these lines of code, in this order:

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

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

The first method call will invoke the RegisterAreamethod of every found xxxAreaRegistrationclass. And, inside this configuration you'll usually have something like this:

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

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

If you want to have Web API controllers inside this area, you must add the Web API route before this one, like so:

如果你想在这个区域内有 Web API 控制器,你必须在这个区域之前添加 Web API 路由,如下所示:

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

In this case, I'm assuming that you want to invoke your API controllers using an url like this: /AreaName/Api/ControllerName/Id.

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

I usually store the Web API controllers inside an Apifolder inside the area folder, but it doesn't matter where you put them. Take into account that the API controllers will be found wherever they are and, if you use the same name for them in different areas, you'll get conflicts: they're found by the class name, not by the fully qualified (namespaced) name.

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

In few words: there's no real support for areas, but you can include them in their own folders inside the areas, and make them available on URL's which look like the ones of MVC controllers inside areas.

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

Supporting route namespaces

支持路由命名空间

What if you want to have Web API controllers with the same name in different areas? If you really want to give real support for areas to Web API controllers, you have to implement and register a custom IHttpControllerSelector.

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

You have a good explanation, and a sample implementation here: ASP.NET Web API: Using Namespaces to Version Web APIs

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

This sample uses namespaces for versioning, but the code can be slightly modified to support areas namespaces.

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

回答by Eric Boumendil

ASP.NET MVC 4 doesn't support WebAPI in Areas.

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

It is possible to extend DefaultHttpControllerSelectorto do this, but you should carefully read this excellent (and short) article: ASP.NET MVC 4 RC: Getting WebApi and Areas to play nicely. It works great.

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

I've successfully tested this solution with portable areas (MVCContrib). Basically, you have to:

我已经成功地使用可移植区域 ( MVCContrib)测试了此解决方案。基本上,您必须:

  • Put extension methods "AreaRegistrationContextExtensions" in the PA project (required from PortableAreaRegistration.RegisterArea()method): you can copy the static class into the PA project but I suggest to put it into a shared project.
  • Add the class "AreaHttpControllerSelector" (inherited from DefaultHttpControllerSelector) into the host project.
  • Add to Global.asax App_Start() the following line:

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

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

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

There is one caveat with the implementation of AreaHttpControllerSelector: the area name must correspond to the ApiController's namespace. For example, this is my PortableAreaRegistrationclass:

实现有一个警告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"; }
        }
    }
}

回答by Jon Bates

Make sure you register the API route before the default route, else the default route will greedily capture everything!

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

回答by Jon Bates

Just for completion, the following attributes exists, which could help people out of a bind (who won't follow eric's advice above...)

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

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