Why does the ASP.NET Web Api model binding use a parameter type to determine the source of a value?

Since after a few days I am trying to create my own api web controller. Duo for other conventions I need to use a mail request to create an object. To get specific, Im has this controller with this action:

public class ReservationController : ApiController { [HttpPost] public void Create(int roomId, DateTime arrivalDate) { //do something with both parameters } } 

This code does not work when I run the mail request, I get exception 404, something like this:

No actions were found on the Some controller that match the query.

The reason for this is that simple types are read from the query string, complex types from the body, according to this aricle . The web api uses parameters to match the action with the request and therefore cannot match my action with the request.

I know that I can use the [frombody] tag, but you can only apply it to one parameter, and I have 2. I also know that I can create a wrapper object that has both parameters, but I'm not wanting use wrappers for all my calls.

Therefore, I know that I can get around this with these methods. I also think that this is due to the fact that the body of the mail request can be read only once. But my real question is:

Why is the type of the parameter determined by the source of the parameter, and not its availability, especially if the agreements indicate what you should do, for example, a request to create to create? In MVC this is so, why is it not in a web api?

Yours faithfully,

Bhd

FINAL UPDATE As I get some advances, probably more people are facing the same issue. As a result, this comes to the following: Web-Api! = MVC. This is simply not the same, and the web api team made various design decisions than the mvc team, I think.

+6
source share
3 answers

It looks like you have a fundamental misunderstanding of how the Web API works.

Web API routing is disconnected from words, not method names. "SomeMethod" actually translates to zero useful information for the Web API. As a result, if I publish

 api/some/some?id=1 

OR

 api/some/somemethod?id=1 

OR EVEN

 api/some/?id=1 

and SomeMethod's endpoint is ONLY available POST, it will hit that endpoint.

As such, first of all, make sure that you have only one POST on this api controller. If you do this, then POST for it from any test client using any of the query strings will work fine.

+4
source

You can use the [FromBody] attribute for the parameter to make it read from the HTTP POST body instead of Uri. This contradicts the [FromUri] attribute, which does the opposite.

 [HttpPost] public void SomeAction([FromBody] int id) { //do something with id } 

Are you sure you are actually setting the identifier in the body? It can also be a routing problem. If this still does not work, perhaps you should use Fiddler and copy the RAW output of your HTTP message here.

If you are packing multiple values โ€‹โ€‹into a body, for example using JSON, you should use a model that should be automatically deserialized for:

 public class PostModel { public int ID { get; set; } public int SomeOtherID { get; set; } } [HttpPost] public void SomeAction(PostModel postModel) { //do something with postModel.ID and postModel.SomeOtherID } 
+1
source

You can do this right out of the box in WebAPI, at least in version 2.2 (.Net version 4.5.2). Your controller is correct. Using your controller, if you call it using HTTP POST, like this (verified via Fiddler):

 http://localhost:58397/api/Reservation?roomId=123&arrivalDate=2015-12-17 

You will get the correct values โ€‹โ€‹roomId = 123 and arrivalDate = 12/17/2015.

I suspect something is wrong with your call to WebAPI. Perhaps you can send this call if you still do not want it to work.

0
source

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


All Articles