Reputation: 2153
I created a project using the default ASP.NET Core MVC template. I would like to also create a RESTful API under /api/{Controller}
. I added a new Web API controller (standard Web API controller class template) but I can't call it. I get an error saying that the page cannot be found. I tried adding a route in Startup.cs but it doesn't do anything:
app.UseMvc(routes =>
{
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(name: "api", template: "api/{controller=Admin}");
});
EDIT:
Like I said, it's all default templates. Here's the Web API Controller that I added:
[Route("api/[controller]")]
public class AdminController : Controller
{
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post([FromBody]string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
Upvotes: 29
Views: 37544
Reputation: 508
I tried to call https://localhost:7052/api/TranslationsJS/GetAll but I got 404 not found.
So my issue was that I had a typo in action. I defined a route name instead route template(path).
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class TranslationsJSController : ControllerBase
{
[HttpGet(Name = "GetAll")] // this didn't work because it is route name
[HttpGet("GetAll")] // this worked because it is route template(path)
public ActionResult<Dictionary<string, string>> GetAll()
{
var resourceSet = TranslationsJS.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
var translationsJs = new Dictionary<string, string>();
foreach (DictionaryEntry entry in resourceSet)
{
translationsJs.Add(entry.Key.ToString(), entry.Value.ToString());
}
return translationsJs;
}
}
In program.cs
builder.Services.AddControllersWithViews();
...
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
More info:
https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-7.0#route-name
https://csharp-video-tutorials.blogspot.com/2017/02/generating-links-using-route-names-in.html
Upvotes: 0
Reputation: 31
Running existing .net core MVC:
In order to add api controllers to existing .net core 6 mvc application, Open Program.cs file, add following codes:
//for apis
builder.Services.AddRazorPages();
builder.Services.AddControllers();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
Now go ahead and add a new controller:
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
//endpoint: http://localhost:5207/api/test/strings
[HttpGet("strings")]
public IActionResult TestMethod()
{
return Ok(new string[]{
"23", "24"});
}
}
Testing Endpoint here
This works for me in .net core 6
Upvotes: 3
Reputation: 247008
Two things.
First, when using convention-based routing, more specific routes should come before more generic routes to avoid route conflicts.
app.UseMvc(routes =>
{
routes.MapRoute(name: "api", template: "api/{controller=Admin}");
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});
Secondly, you are already using attribute routing on the controller so should have been able to route to the controller except for the fact that you do not have a routing template on the controller that would accept /api/{Controller}
That would require a default route.
[Route("api/[controller]")]
public class AdminController : Controller {
[HttpGet("")] //Matches GET api/admin <-- Would also work with [HttpGet]
public IActionResult Get() {
return Ok();
}
[HttpGet("{id}")] //Matches GET api/admin/5
public IActionResult Get(int id) {
return Ok("value");
}
//...other code removed for brevity
}
Upvotes: 12
Reputation: 111
I had luck doing this with v3.1:
Add Folder Controllers to the project. Add Controller, named TestController, to the folder. Then add the following to the Startup.cs:
services.AddControllers();
to
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddControllers();
}
and:
endpoints.MapControllers();
to
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
Then I was able to call /api/Test.
Upvotes: 11
Reputation: 731
If someone still have problem in adding webapi to .net core MVC, just inserting [ApiController]
and [Route("api/[controller]")]
attributes before class solves the problem:
[Route("api/[controller]")]
[ApiController]
public class ListController
{ ... }
I didn't added a route mapping in Startup.cs
and still working well. The version of .net that I am using is 2.1.402
Upvotes: 8
Reputation: 2153
After updating to the latest version of ASP.NET Core, v2.0.1 (the one that needs VS2017), the problem resolved itself. I think it was probably a bug or shortcoming in the old version.
Upvotes: 3
Reputation: 78
Try setting name to "Admin"
app.UseMvc(routes =>
{
routes.MapRoute(
name: "Admin",
template: "api/{controller=Admin}");
});
Upvotes: 0