When writing Web Api method in .Net is it necessary to have the method name prefix with HTTP code like GET, Post etc? - asp.net-web-api

When writing Web Api method in .Net is it necessary to have the method name prefix with HTTP code like GET, POST etc?
Example:
public IEnumerable<Product> GetAllProducts();
public IHttpActionResult GetProduct(int id);
public IHttpActionResult PostProduct(Product prod);

No, it's not necessary, but it's one of several conventions to map HTTP verbs to action methods. You could, for example, do this:
[HttpGet]
public IHttpActionResult AllProducts();
or this:
public IHttpActionResult GetAllProducts();
and they would both handle GET requests.

If you utilise attribute routing you don't need to.
Have a read of the docs
eg:
The following example maps the CreateBook method to HTTP POST requests.
[Route("api/books")]
[HttpPost]
public HttpResponseMessage CreateBook(Book book) { ... }

Related

MVC Request did not match any routes

I have following controller where I need to find routes for various actions:
[Route("api/[controller]/[action]")]
[EnableCors("MyPolicy")]
public class UserController : Controller
{
IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService;
}
[HttpGet]
public async Task<IEnumerable<User>> Get()
{
return await _userService.GetAllAsync();
}
[HttpGet("{id}")]
public async Task<User> Get(object id)
{
return await _userService.FirstOrDefaultAsync(x => x.Id == (ObjectId)id);
}
}
According to https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing
such request http://localhost:55556/User/Get should be passed to a route but I get the following message when running in Visual Studio debug:
Request starting HTTP/1.1 GET http://localhost:55556/User/Get
dbug: Microsoft.AspNetCore.Builder.RouterMiddleware[1]
Request did not match any routes.
What could be wrong here? Is there any way to list all possible routes? Or make sure what controllers are registered?
Look on your route template definition more carefully:
[Route("api/[controller]/[action]")]
It has a api/ string prefix (const) and so MVC middleware experts requests like
http://localhost:55556/api/User/Get
not
http://localhost:55556/User/Get
Also, if talking in the scope of REST, it is a bad idea to use routes like User/GET, User/POST etc. For such purpose, the corresponding HTTP Method (Gey, Post, Put, ...) is defined and used. In other words, you have a redundant duplication right now, as a request, for example, from curl looks like:
curl -X GET 'http://localhost:55556/User/Get`

web api 2 controller multiple post methods

I have a controller with the default post method. I want to add one more with a different name and action. The problem is when I make the request POST (http://localhost:57926/api/Users/Login) it doesn't execute Login method, it executes the default PostUser method.
How can I fix this?
// POST: api/Users
[ResponseType(typeof(User))]
public IHttpActionResult PostUser(User user){
//Some code
}
[HttpPost]
[Route("Login")]
public IHttpActionResult Login(JObject form)
{
//some code
}

Why do we have to specify FromBody and FromUri?

Why are the FromBody and FromUri attributes needed in ASP.NET Web API`?
What are the differences between using the attributes and not using them?
When the ASP.NET Web API calls a method on a controller, it must set values for the parameters, a process called parameter binding.
By default, Web API uses the following rules to bind parameters:
If the parameter is a "simple" type, Web API tries to get the value from the URI. Simple types include the .NET primitive types (int, bool, double, and so forth), plus TimeSpan, DateTime, Guid, decimal, and string, plus any type with a type converter that can convert from a string.
For complex types, Web API tries to read the value from the message body, using a media-type formatter.
So, if you want to override the above default behaviour and force Web API to read a complex type from the URI, add the [FromUri] attribute to the parameter. To force Web API to read a simple type from the request body, add the [FromBody] attribute to the parameter.
So, to answer your question, the need of the [FromBody] and [FromUri] attributes in Web API is simply to override, if necessary, the default behaviour as described above. Note that you can use both attributes for a controller method, but only for different parameters, as demonstrated here.
There is a lot more information on the web if you google "web api parameter binding".
The default behavior is:
If the parameter is a primitive type (int, bool, double, ...), Web API tries to get the value from the URI of the HTTP request.
For complex types (your own object, for example: Person), Web API tries to read the value from the body of the HTTP request.
So, if you have:
a primitive type in the URI, or
a complex type in the body
...then you don't have to add any attributes (neither [FromBody] nor [FromUri]).
But, if you have a primitive type in the body, then you have to add [FromBody] in front of your primitive type parameter in your WebAPI controller method. (Because, by default, WebAPI is looking for primitive types in the URI of the HTTP request.)
Or, if you have a complex type in your URI, then you must add [FromUri]. (Because, by default, WebAPI is looking for complex types in the body of the HTTP request by default.)
Primitive types:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post([FromBody]int id)
{
}
// api/users/id
public HttpResponseMessage Post(int id)
{
}
}
Complex types:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post(User user)
{
}
// api/users/user
public HttpResponseMessage Post([FromUri]User user)
{
}
}
This works as long as you send only one parameter in your HTTP request. When sending multiple, you need to create a custom model which has all your parameters like this:
public class MyModel
{
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
}
[Route("search")]
[HttpPost]
public async Task<dynamic> Search([FromBody] MyModel model)
{
// model.MyProperty;
// model.MyProperty2;
}
From Microsoft's documentation for parameter binding in ASP.NET Web API:
When a parameter has [FromBody], Web API uses the Content-Type header
to select a formatter. In this example, the content type is
"application/json" and the request body is a raw JSON string (not a
JSON object). At most one parameter is allowed to read from the
message body.
This should work:
public HttpResponseMessage Post([FromBody] string name) { ... }
This will not work:
// Caution: This won't work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
The reason for this rule is that the request body might be stored in a
non-buffered stream that can only be read once.
Just addition to above answers ..
[FromUri] can also be used to bind complex types from uri parameters instead of passing parameters from querystring
For Ex..
public class GeoPoint
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
[RoutePrefix("api/Values")]
public ValuesController : ApiController
{
[Route("{Latitude}/{Longitude}")]
public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
}
Can be called like:
http://localhost/api/values/47.678558/-122.130989
When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is "application/json" and the request body is a raw JSON string (not a JSON object).
At most one parameter is allowed to read from the message body. So this will not work:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
The reason for this rule is that the request body might be stored in a non-buffered stream that can only be read once.
Please go through the website for more details:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

What advantage do we get if we specify Frombody and FromUri attribute in web api?

What are the benefits/advantages we get if we specify this frombody and fromuri attribute in web-api?
Web API parameter binding expects simple type values coming from query string, and complex types like array coming from the body of the request. Hence if you have an action method like this one:
public class EmployeesController : ApiController
{
public IHttpActionResult Get(int id, string[] names)
{
return Ok("Method Called");
}
}
,and if you want to formulate your request like this:
/api/employees?id=1&names=Fred&names=Anna
, then without [FromUri] the value of "names" parameter won't be bound.
So your API method must be like this in order to get all parameters bound:
public IHttpActionResult Get(int id,[FromUri] string[] names)
{
return Ok("Method Called");
}
More from here: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

ASP.NET Web API method for both GET and POST

I have the following method in my API:
[HttpGet]
public HttpResponseMessage ExecuteCommand()
{
// logic
}
This method currently serves only the http GET method. I would also like it to respond to http POST method - Is that possible? or do I have to duplicate the method?
Thanks
You can do it like this
[AcceptVerbs("Get", "Post")]
public HttpResponseMessage ExecuteCommand()
{
// logic
}
This is possible since the constructor looks like this, and takes an array of strings.
public AcceptVerbsAttribute(
params string[] verbs
)

Resources