Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

web api 2 area routes

I am using asp.net mvc 5 and web api 2. For the asp.net mvc 5 project I have everything working... but new I am trying to add web api 2 routes... when I am using areas.

I have the web api 2 controller working at the project root:

 //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")
                };
            }

        }
    }

So I am assuming my Global.asax, my routeconfig.cs and my webapiconfig.cs are correct ... (not shown)...

But now I am trying to get the web api 2 in my AREAS working...

I have read everything I could find on the web and this seems like it should work:

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 }
            );
        }
    }
}

My controller code is:

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();
        }
    }
}

I have tried the controller with and without the attribute naming [Route]... and I can't get either get to work...

Both the simple case

    public HttpResponseMessage Get()

and the "real" case

  public IEnumerable<VwAuditModel1> GetAuditModels()

return the same result. From the browser, using

http://localhost:64167/WorkOrder/api/AuditModelApi

and

http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels

I get the following:

<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>
like image 913
user2040850 Avatar asked Mar 18 '15 14:03

user2040850


People also ask

Which of the following types of routing is supported in Web API 2?

Web API 2 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API.

How do I specify a route in Web API?

The default route template for Web API is "api/{controller}/{id}". In this template, "api" is a literal path segment, and {controller} and {id} are placeholder variables. When the Web API framework receives an HTTP request, it tries to match the URI against one of the route templates in the routing table.

How many types of routing are there in Web API?

Web API supports two types of routing: Convention-based Routing. Attribute Routing.

What is the difference between MVC routing and Web API routing?

In MVC, by default HTTP verb is GET for using others HTTP verbs you need defined as an attribute but in Web API you need to define as an method's name prefix.


1 Answers

First, you should register the route with the Area it belongs to, that only makes sense, so inside your AreaNameAreaRegistration class be sure to add using System.Web.Http so you get the extension method MapHttpRoute, it's not part of System.Web.Mvc.

The order above is a bit off, which is causing the 404. Add the following Route:

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

If you want to get fancy and append the Area Name from the property AreaName (of course you care about good coding practices ;)):

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

This will correct the 404 issue. In the Web API module by default it first scans for "api" to determine where to look for the controller (otherwise it'll be confused, it's not magic) so api needs to be first when dynamically appending the Area Name and Controller. Of course you CAN change this order by hard-coding your routes, but I don't recommend that because you'll need to provide every route and every controller in the route config or using the RouteAttribute.

Plus, with "api" first it will make a nice standard looking URL for you and your users instead of having API all over the place. Here are some samples:

http://site/api/members/myAccount/update
http://site/api/members/myAccount/get/12345
http://site/api/members/contacts/getByOwnerId/12345

Hope this helps!

Zev

like image 188
Zev Butler Avatar answered Nov 11 '22 05:11

Zev Butler