ASP.NET Web API Routing Using PUT

I am trying to configure the routing of the web API so that in my opinion it will be very simple. However, the routing in the Web API does not seem to match the various HTTP verbs. Suppose I have this controller with these actions ...

public class AvalancheController : ApiControllerBase { // GET api/avalanche public IEnumerable<Avalanche> Get() {} // GET api/avalanche/5 public Avalanche Get(int id) {} // GET api/avalanche/ActionTest/5 [ActionName("ActionTest")] public Avalanche GetActionTest(int id) {} // GET api/avalanche/ActionTest/2 [ActionName("ActionTest2")] public Avalanche GetActionTest2(int id) {} // POST api/avalanche public void Post([FromBody]Avalanche value) {} // PUT api/avalanche/5 public void Put(int id, [FromBody]Avalanche value) {} // PUT api/avalanche/test/5 [ActionName("Test")] public void PutTest(int id, [FromBody]Avalanche value) {} // DELETE api/avalanche/5 public void Delete(int id) {} } 

and I have the following routes defined ...

  config.Routes.MapHttpRoute( name: "ActionRoutes", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional }, constraints: new { controller = "Avalanche", action = "(ActionTest|ActionTest2|Test)" } ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); 

Then I get the following routes:

 GET api/Avalanche/ActionTest/{id} GET api/Avalanche/ActionTest2/{id} PUT api/Avalanche/Test/{id} GET api/Avalanche POST api/Avalanche DELETE api/Avalanche/{id} 

Why doesn't the default PUT route start? What is the difference between default GET routing and default PUT? I tried to decorate functions in every imaginable way, but I get the same results.

Basically I want to know how to get the default PUT route to pick up. If you have suggestions for changing these routes, so that I donโ€™t have a route for each controller, to indicate the names of the actions, which would also be fantastic.

Thanks!

Yang

EDIT: This morning I noticed that the next route is also undefined.

 GET api/Avalanche/{id} 
+4
source share
1 answer

Glad you found a solution to your problem. But I would provide my feedback based on my training with REST services. The idea for a REST web service is to resolve each URL to a resource (or possibly an entity), and depending on HttpVerb, the work will be decided. In this case, you have three GET operations that work perfectly with your changes.

But I think that the controllers can also be regrouped to have a single GET operation and have a single responsibility, thus, better maintainability. For example:

Avalanchecontroller

 public class AvalancheController : ApiControllerBase { public IEnumerable<Avalanche> GET() { } public void POST(Avalanche avalanche) { } } 

We can assume that all the avalanches on the upper level deal with all the avalanches, below are the operations that need to be determined.

GET: returns the entire avalanche
POST: inserts a new avalanche
PUT: not used
REMOVE: not used

AvalancheDetailsController

 public class AvalancheDetailsController : ApiControllerBase { public Avalanche GET(int id) { } public int PUT(int id) { } public int DELETE(int id) { } } 

We can assume that we are talking about a single avalanche, below are the operations that need to be determined.

GET: returns a single avalanche
POST: not used
PUT: updates one avalanche
DELETE: removes a single avalanche

Now I assume that we have a clear distinction between controllers. There may be different GET operations in the OP you were talking about, but it only returns one Avalanche . So, I would modify the GET method to take the object as input and check ie,

 public class AvalanceRequest { public int? Id {get;set;} public string Name {get;set;} } public class AvalancheDetailsController : ApiControllerBase { public Avalanche GET(AvalanceRequest request) { //write business logic based on parameters if(request.Id.HasValue) //return avalanche; if(request.Name.IsNullOrEmpty()) //return avalanche } //other methods } 

Working with a URL, I really did not work with WebAPI, but ServiceStack tried to develop REST services. It allows you to attach url regardless of controller names.

Url
api / Avalanche -> AvalancheController (Operations are called based on HttpVerb)
api / Avalanche / Id โ†’ AvalancheDetailsController (Operations are called based on HttpVerb)

I do not know if the URL can be attached in the same way in the WebAPI, otherwise you will have a default configuration and a call through. api / Avalanche and api / AvalancheDetails / id.

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

I apologize for the long post, I hope this makes sense.

+1
source

Source: https://habr.com/ru/post/1469153/


All Articles