web api 2区域路线

use*_*850 12 asp.net-mvc-routing asp.net-mvc-areas asp.net-mvc-5 asp.net-web-api2

我正在使用asp.net mvc 5和web api 2.对于asp.net mvc 5项目,我有一切正常工作......但新的我正在尝试添加web api 2路由...当我使用区域时.

我有web api 2控制器在项目根目录下工作:

 //this is working 
   namespace EtracsWeb.Controllers
    {
        public class TestController : ApiController
        {
            //localhost:port/api/test ...this is working
            [HttpGet]
            public HttpResponseMessage Get()
            {

                return new HttpResponseMessage()
                {
                    Content = new StringContent("GET: Test message")
                };
            }

        }
    }
Run Code Online (Sandbox Code Playgroud)

所以我假设我Global.asax,我routeconfig.cs和我webapiconfig.cs的正确......(未显示)......

但是现在我想在我的AREAS工作中获得web api 2 ...

我已经阅读了我在网上找到的所有内容,这似乎应该可行:

namespace EtracsWeb.Areas.WorkOrder
{
    public class WorkOrderAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "WorkOrder";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {

            context.Routes.MapHttpRoute(
                    name: "AuditModel_Api",
                    routeTemplate: "WorkOrder/api/AuditModelApi/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );

        //default
            context.Routes.MapHttpRoute(
                    name: "WorkOrder_Api",
                    routeTemplate: "WorkOrder/api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );

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

我的控制器代码是:

namespace EtracsWeb.Areas.WorkOrder.ApiControllers
{
    public class AuditModelApiController : ApiController
    {
        IManufacturerStopOrderModelService auditModelService = new WorkOrder.Services.VWAuditModelService(UserSession.EtracsUserID, UserSession.ProgramID, UserSession.EtracsSessionID, UserSession.ConnectionString);

        [HttpGet]
        [Route("AuditModelApi")]
        public HttpResponseMessage Get()
        {

            return new HttpResponseMessage()
            {
                Content = new StringContent("GET: Test message")
            };
        }

        [Route("AuditModelApi/AuditModels")]
        public IEnumerable<VwAuditModel1> GetAuditModels()
        {
                return auditModelService.GetModels();
        }

        public IHttpActionResult UpdateAuditMode()
        {
            //example of what can be returned ... NotFound, Ok ... look into uses...

            VwAuditModel1 result = new VwAuditModel1();
            return Ok(result);

            return NotFound();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试过控制器有和没有属性命名[Route]...我无法得到工作......

两者都是简单的案例

    public HttpResponseMessage Get()
Run Code Online (Sandbox Code Playgroud)

和"真实的"案件

  public IEnumerable<VwAuditModel1> GetAuditModels()
Run Code Online (Sandbox Code Playgroud)

返回相同的结果.从浏览器中使用

http://localhost:64167/WorkOrder/api/AuditModelApi
Run Code Online (Sandbox Code Playgroud)

http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels
Run Code Online (Sandbox Code Playgroud)

我得到以下内容:

<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels'.
</Message>
<MessageDetail>
No route providing a controller name was found to match request URI 'http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels'
</MessageDetail>
</Error>
Run Code Online (Sandbox Code Playgroud)

小智 5

首先,你应该使用它所属的区域注册路由,这才有意义,所以在你的AreaNameAreaRegistration类中一定要添加using System.Web.Http以便你获得扩展方法MapHttpRoute,它不是System.Web.Mvc.

上面的顺序有点不对,是404导致的,添加如下Route:

context.Routes.MapHttpRoute(
            name: "AreaNameWebApi",
            routeTemplate: "api/AreaName/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
Run Code Online (Sandbox Code Playgroud)

如果您想获得幻想并从属性中附加区域名称AreaName(当然您关心良好的编码实践;)):

context.Routes.MapHttpRoute(
            name: "AreaNameWebApi",
            routeTemplate: string.Concat("api/", AreaName, "/{controller}/{id}"),
            defaults: new { id = RouteParameter.Optional }
        );
Run Code Online (Sandbox Code Playgroud)

这将更正 404 问题。默认情况下,在 Web API 模块中,它首先扫描“api”以确定在哪里寻找控制器(否则会混淆,这不是魔术),因此在动态附加区域名称和控制器时需要首先使用 api。当然,您可以通过对路由进行硬编码来更改此顺序,但我不建议这样做,因为您需要在路由配置中提供每条路由和每个控制器,或者使用RouteAttribute.

另外,首先使用“api”,它将为您和您的用户创建一个漂亮的标准 URL,而不是到处都有 API。以下是一些示例:

http://site/api/members/myAccount/update
http://site/api/members/myAccount/get/12345
http://site/api/members/contacts/getByOwnerId/12345
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

泽夫


小智 4

您需要HttpConfigurationGlobalConfiguration对象获取实例并MapHttpAttributeRoutes()从 的RegisterArea()方法内部调用该方法AreaRegistration.cs

    public override void RegisterArea(AreaRegistrationContext context) 
    {
        GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

        //... omitted code  
    }
Run Code Online (Sandbox Code Playgroud)

最后你必须在WebApiConfigremoveconfig.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 }
        );
    }
}
Run Code Online (Sandbox Code Playgroud)