2
votes

I am working on an API. I have an "AbstractController.cs" and I am having difficulties calling a GET with two parameters.

[Route("api/[controller]")]
[ApiController]
public class AbstractController : ControllerBase
{
    // GET: api/Abstract
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "missing implementation" };
    }

Going to https://localhost:44363/api/abstract/ generates this. ["missing implementation"] Awesome!

Now I need to make the Get method that passes in a show year, and code to a SQL query. Easy enough?

// GET: api/Abstract?ShowYear=2019&ShowCode=248621
    [Route("api/{controller}/{ShowYear}/{ShowCode}")]
    [HttpGet]
    public Abstract Get(int ShowYear, int ShowCode) // GetAbstractByYearAndSHCode
    {
        string x = "";
        return new Abstract();
    }

No matter what I do I can't get this method to breakpoint/enter execution! I'm guessing it's a routing issue, but I've tried most tenable ways of calling the endpoint.

enter image description here

Now I check the MS Documentation like any self-respecting-learning-programmer would. https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-3.1

Endpoint routing in ASP.NET Core 3.0 and later:

Doesn't have a concept of routes. Doesn't provide ordering guarantees for the execution of extensibility, all endpoints are processed at once.

GULP Sounds scary.

I haven't touched my middleware at this point.

All examples I've looked at don't have my "MapControllers();" method in their Startup.cs. This is because it's new to .NET Core 3.0/3.1 The method: "Adds endpoints for controller actions to the IEndpointRouteBuilder without specifying any routes."

OK, so do I have to manually specify the route here still? I did this, and it sorta works.

Well, it breakpoints in the startup.cs now when I go to https://localhost:44363/api/abstract/2019/287 enter image description here

Wait, it's not doing ANYTHING with my controller code! Why?

The following (also above) code ends up declaring as a null in the startup.cs

                    var controller = context.Request.RouteValues["Abstract"];

Hoping to learn what I'm doing wrong.

MapGet("/api/abstract/{showYear}/{showCode}", ...);

Isn't this code responsible for mapping that route with the controller named AbstractController.cs in my Controllers folder? Not hitting any breakpoints.

Edit: Reading through this which compares the differences in the Startup.cs from .Net Core 2, 2.2, MVC projects vs 3.0 I have a good feeling reading all of this, I will find the issue. https://andrewlock.net/comparing-startup-between-the-asp-net-core-3-templates/ Edit.. nevermind didn't find a resolution.

Edit 2:

Completely commenting out this troublesome code in startup.cs:

endpoints.MapGet("/api/abstract/{showYear}/{showCode}", async context =>
            {
                var controller = context.Request.RouteValues["Abstract"];

                var showYear = context.Request.RouteValues["showYear"];
                var showCode = context.Request.RouteValues["showCode"]; // just an example.
                //await context.Response.WriteAsync($"Hello {showYear} is your year, {showCode} for the code!");
                //GetAbstractByYearAndSHCode();
            });
            
            endpoints.MapGet("/api/abstract/{showYear}", async context =>
            {
                var name = context.Request.RouteValues["name"];
                await context.Response.WriteAsync($"Hello {name}!");
            });

Resolves my issue of not being able to reach the controller.

enter image description here

https://localhost:44363/api/abstract/2019 hits, and the id value is 2019. Great. https://i.imgur.com/rmHyDPg.png the output looks great.

I am still not able to use > 1 parameter. How do I simply use the Year, and ShowCode paramaters? What's the syntax? https://localhost:44363/api/abstract/2019

2
If you create a new project right now in .NC3.1 the default WeatherForecastController.cs value is: [Route("[controller]")] - Dont
Interesting. I thought I'd only ever seen it with curlies. Speaking of starting over; does it work with your new project? - Caius Jard
What do you mean starting over? Let me see. i.imgur.com/UoBJ3ut.png here is the controller, freshly generated. i.imgur.com/BX8WVwc.png - Dont
That new project you've made; does it work? Press play, open postman, add the url, hit send request- does it call the action? - Caius Jard
i.imgur.com/OwEp7p5.png Yes. Just how it works in the original one actually. Yes. - Dont

2 Answers

1
votes

Just add the parameters to your attribute


[HttpGet("{ShowYear}/{ShowCode}")]

1
votes

The "api/abstract" route is already used by the first method. You cannot use it again for other actions. Create a new one as shown inline.

[HttpGet("{GetAbstractByYearAndSHCode}",Name = "GetAbstractByYearAndSHCode")]
public Abstract Get(int ShowYear, int ShowCode) // GetAbstractByYearAndSHCode
{
    string x = "";
    return new Abstract();
}

And call the url as shown:

https://localhost/api/abstract/GetAbstractByYearAndSHCode?ShowYear=1&ShowCode=5