5
votes

The structure:

+ MyProj
   + Areas
       + Configuration
          - Pages
          - ConfigurationApiController.cs

To create controller without Controllers folder was proposed by VS2017 and it is ok for me since I use Razor Pages and do not need Controllers folder:

enter image description here

Those doesn't work:

Controller defined:

[Route("api")]
[Produces("application/json")]
[ApiController]
public class ConfigurationApiController : ControllerBase
{
    private readonly ApplicationSettings applicationSettings;
    [HttpGet]
    public ActionResult GetUsers()
    {

Mvc routing configured standard way:

app.UseMvc(routes =>
            {

                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

How to route to GetUsers action of ConfigurationApiController ?

2

2 Answers

6
votes

Modify the api route and add the Area Attribute to provide the area name for [area] route.

    [Area("Configuration")]
    [Route("[area]/api/[controller]")]
    [ApiController]
    public class ConfigurationApiController : ControllerBase
    {
    }

That's all, and it can be accessed at http://localhost:8080/Configuration/api/ConfigurationApi

2
votes

Some other routing options:

  1. Using AspNetCore.RouteAnalyzer working option found: http://localhost:8080/api (yes, without action)

  2. After removing web APIs attributes

   // [Route("api")]
   // [Produces("application/json")]
   // [ApiController]

then http://localhost:8080/ConfigurationApi/GetUsers

it could be ok but there is no area in the routing and it seems "routing to the area by conventions" doesn't work is asp core: ASP Core: how to configure area for api controller without AreaAttribute (or how to enable convention area routing for Api controller)? and https://github.com/aspnet/AspNetCore/issues/7042

Also in this case ContentResult { Content = json, ContentType = "application/json" } should be return but this is ok for me since I prefer to use in place serialization instead of stream serializers.

  1. This routes to http://localhost:8080/Configuration/api
    [Area("Configuration")]
    [Route("[area]/api")] 
    [Produces("application/json")]
    [ApiController]

other option: [Route("[area]/api/[action]")] routes to http://localhost:8080/Configuration/api/GetUsers

when removing area attribute throws the run-time error Error: While processing template '[area]/api', a replacement value for the token 'area' could not be found. Available tokens: 'action, controller'. To use a '[' or ']' as a literal string in a route or within a constraint, use '[[' or ']]' instead.

    //[Area("Configuration")]
    [Route("[area]/api")]
    [Produces("application/json")]
    [ApiController]

To support @Url.Action(action: "myArea", controller: "myControllerApi") routing should be configured manually.

Asp Core routes:

 app.UseMvc(routes =>
        {
        routes.MapRoute(
        name: "defaultArea",
        template: "{area:exists}/{controller}/{action}"); // matches only those where area route value is defined
        });

Asp Core 3 routes (startup Configure):

 app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
            endpoints.MapControllerRoute(
                name: "defaultArea",
                pattern: "{area:exists}/{controller}/{action}");
        });