LP13
LP13

Reputation: 34109

Routing is not working for web api with realtions

I am creating web api using asp.net core. The api end point is logically mapped to resource's relations based on guidelines here So my API looks like

      http://tax.mydomain.com/api/v1/clients/1/batches/12/start

Where Client is parent of Batch, 1 is clientid and 12 is batchid, and Start is POST action method.

Here is the corresponding controller

public class TaxController : Controller
{
    [HttpPost]
    [Route("clients/{clientid}/batches/{batchid}/start")]
    public void Start([FromRoute]string clientId, [FromRoute]string batchId, 
                      [FromBody]IEnumerable<string> urls)
    {
       // do something
    }
}

since api/v1 is common to all controllers i configured that in startup's Configure method. Also i want Home as default controller.

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
      app.UseMvc(routes =>
      {
        routes.MapRoute("default","api/v1/{controller=Home}/{action=Index}/{id?}");
      });
    }

However client is getting not found error for api http://tax.mydomain.com/api/v1/clients/1/batches/12/start

Upvotes: 1

Views: 2099

Answers (2)

Tseng
Tseng

Reputation: 64150

There are two things wrong with your setup

  1. You call http://tax.mydomain.com/clients/1/batches/12/start but you don't have specified the controller name within it. This route looks for a controller named ClientsController. So the correct url would have to be http://tax.mydomain.com/tax/clients/1/batches/12/start instead
  2. You seem to be using default MVC/Viewbased route, but your url suggest you use WebAPI.

    When you use WebAPI to create a Rest service, you don't have any actions. Instead, actions map to the Http Verbs (GET (Read), PUT (update/replace), POST (insert), DELETE).

    So for REST Services your default route should look like this instead: api/v1/{controller=Home}/{id?}

Upvotes: 0

Set
Set

Reputation: 49779

Any controller methods that do not have a route attribute use convention-based routing.

When you use [Route] attribute, you define attribute routing and so conventional routing is not used for that action/controller. Therefore, your controller is accessible by

http://tax.mydomain.com/clients/1/batches/12/start

As an option, you can use the fact, that attribute routes can be combined with inheritance. Set a Route attribute on the entire controller and this will work as route prefix (the same behavior as [RoutePrefix] attribute in WebApi):

[Route("api/v1")]
public class TaxController : Controller
{

}

More general example from routing documentation:

[Route("api/[controller]")]
public abstract class MyBaseController : Controller { ... }

public class ProductsController : MyBaseController
{
   [HttpGet] // Matches '/api/Products'
   public IActionResult List() { ... }

   [HttpPost("{id}")] // Matches '/api/Products/{id}'
   public IActionResult Edit(int id) { ... }
}

Upvotes: 1

Related Questions