MVC Request did not match any routes - asp.net-core-mvc

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`

Related

how to set up url routing with sub-paths

i am new to webapi and MVC in general. If I wanted to group my service URLs like this
/api/account/create
/api/account/login
/api/account/resetpass
Am I able to put all 3 method calls in the same controller file and somehow map a particular request to the right method?
Create a Controller named Account and Create 3 [GET, POST, PUT, DELETE] method and name them create , login ,resetpass.
By Default, this is the routing for MVC / API(Id can be optional)
route Template: "api/{controller}/{id}",
Example :
public class AccountController : ApiController
{
[HttpPost]
public string Create()
{
// CODE
}
[HttpPost] // or [HttpGet]
public string Login ()
{
// CODE
}
[HttpPost]
public string Resetpass()
{
// CODE
}
}
if you had trouble calling them, try to give them a specific route :
[HttpGet("GetSubject/{subject}")]
public int GetSubjectId(String subject)
{
//CODE
}
Please if you get any error or misunderstanding, don't hesitate to post a comment

Is it possible to have two controllers with the same route?

Is it possible to have two controllers in two assemblies with the same Route prefix attribute, but different Route attributes on the actions?
[RoutePrefix("api/route")]
public class Controller1 : ApiController
{
[Route("action1")]
[HttpPost]
public async Task<HttpResponseMessage> Post([FromBody] string body)
{ }
[Route("{id}")]
public async Task<HttpResponseMessage> Delete(string id)
{ }
}
[RoutePrefix("api/route")]
public class Controller2 : ApiController
{
[Route("action2")]
[HttpPost]
public async Task<HttpResponseMessage> Post([FromBody] string body)
{ }
}
This is possible. What was my problem was that the first controller had defined a DELETE action with route "{id}". Since id was an unconstrained parameter Web Api could not see the difference between "api/route/action2" and "api/route/idtodelete".
I ended up creating a regex constraint on the delete which excludes "action2" and allows all alpanumeric characters. Now it works.
[HttpDelete]
[Route("{id:regex(^(?!action2)[a-zA-Z0-9]*$)}")]
If you are use the different Route for all action method than it will be working. But if you are using the same Route prefix with same Route action than it will give an error.

How do I add API Endpoints in ASP.NET?

I would like to register API Endpoints in ASP.NET by just adding few methods in ApiController. A new method there means a new API.
In a random example below:
public class ProductController : ApiController
needs to serve the following Endpoints:
/
/price
/price/discount
Problem here is all endpoints are having a GET request to /, and result in same output as /.
Reference URL and Service Contract
You can place Route annotation at method for which you want to use custom route.
public class CustomersController : ApiController
{
// this will be called on GET /Customers or api/Customers can't remember what default
//config is
public List<Customer> GetCustomers()
{
...
}
// this will be called on GET /My/Route/Customers
[HttpGet, Route("My/Route/Customers)]
public List<Customer> GetCustomersFromMyRoute()
{
...
}
}

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

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) { ... }

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