C#
C#

help

Root Question Message

AntonC
AntonC11/1/2022
ASP.NET Core routing options

Say, I have a single server for some views and some apis, so I'd route views by default, while the api would go under /api. The question is what's the correct way to achieve the routing?
- Am I supposed to use this https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-6.0#areas , stick an [Area("api")] on all api controllers?
- Is there a way to have all api controllers be imported from a separate assembly, making them end up in the right grouping on the bases of assembly? Or by namespace prefix?
- Should I explicitly stick a Route to all controllers?

So to be a bit more clear, I want my api controllers resolving to /api/whatever, while all the rest should go to /. I've read the entire page linked above, but it doesn't really mention such a use case, and suggests no best practices in that regard.
Ideally it would be the second option, but the first one also seems fine, if the constant were to be factored out.
Angius
Angius11/1/2022
I just use an area for my API
Angius
Angius11/1/2022
No, sorry, not even that
Angius
Angius11/1/2022
I just have an /Api directory and API controllers there lol
AntonC
AntonC11/1/2022
How do you map them to /api?
Angius
Angius11/1/2022
namespace Ogma3.Api.V1;

[Route("api/[controller]", Name = nameof(ErrorController))]
[ApiController]
public class ErrorController : ControllerBase
{
    [HttpGet]
    public ActionResult<Result> OnGet([FromQuery] int? code)
    {
        var text = code.HasValue
            ? ReasonPhrases.GetReasonPhrase((int)code)
            : "Unknown Error";
        return new JsonResult(new Result(code, text))
        {
            StatusCode = code ?? 0
        };
    }

    public sealed record Result(int? Code, string Reason);
}

an example
Angius
Angius11/1/2022
My namespaces follow the directories
AntonC
AntonC11/1/2022
Yeah imo that's shit
AntonC
AntonC11/1/2022
the route thing
Angius
Angius11/1/2022
Yeah, most probably lol
Angius
Angius11/1/2022
Just use areas, then
Angius
Angius11/1/2022
You still need [Route("[controller]")] tho
AntonC
AntonC11/1/2022
no i don't?
AntonC
AntonC11/1/2022
Look at the examples in the docs
AntonC
AntonC11/1/2022
ApiController already makes the class attribute-routed only, no?
Angius
Angius11/1/2022
Ah, huh, maybe
AntonC
AntonC11/1/2022
Do you use the explicit route name for something in your app?
Angius
Angius11/1/2022
For the entirety of my API
Angius
Angius11/1/2022
But now you told me I might not need to lol
Angius
Angius11/1/2022
I'll probably refactor it to being an area
AntonC
AntonC11/1/2022
No I mean do you consume it?
Angius
Angius11/1/2022
I do, yeah
Angius
Angius11/1/2022
/api/whatever/...
AntonC
AntonC11/1/2022
I mean the Name
AntonC
AntonC11/1/2022
why do you need to specify it explicitly at all
AntonC
AntonC11/1/2022
[Route("blah", Name = nameof(...))]
AntonC
AntonC11/1/2022
What do you use the name for
Angius
Angius11/1/2022
Ah
Angius
Angius11/1/2022
To generate the URL that I sometimes need
AntonC
AntonC11/1/2022
So you're doing that because by default the name is the name of the class, without the controller part, so you're adding that explicitly, so that you could get the link by doing nameof(WhateverController)
AntonC
AntonC11/1/2022
So I assume there's no built-in function to get the controller name by type?
AntonC
AntonC11/1/2022
Like nameof(WhateverController)[.. ^("Controller".Length)] I guess
AntonC
AntonC11/1/2022
Do you create the link in a way similar to GetLink(controller = nameof(WhateverController), action = nameof(WhateverController.Action))?
Angius
Angius11/1/2022
Yeah, I use the nameof() approach
Angius
Angius11/1/2022
I think in one place I do some substringing because... I don't even remember why, but apparently I had to
AntonC
AntonC11/1/2022
I'm kinda disappointed about this one, seems like a rough edge
AntonC
AntonC11/1/2022
I mean, having to either remove the controller part manually, or rename the routes
Angius
Angius11/1/2022
You could prolly write your own helper
AntonC
AntonC11/1/2022
Yeah, but it's bad ux
AntonC
AntonC11/1/2022
kinda bad anyway
Angius
Angius11/1/2022
Oh sure
AntonC
AntonC11/1/2022
Unhandled exception. System.InvalidOperationException: Action 'fourtynine.StuffApiController.GetStuff (fourtynine)' does not have an attribute route. Action methods on controllers annot
ated with ApiControllerAttribute must be attribute routed.
AntonC
AntonC11/1/2022
huh
AntonC
AntonC11/1/2022
I guess it doesn't imply being attribute-routed, you were right
Angius
Angius11/1/2022
Looks like I wasn't writing those attributes pointlessly then, yay :mweh:
AntonC
AntonC11/1/2022
There's no way it's the right way to do it though, right? I mean, there are tons of repetition
AntonC
AntonC11/1/2022
The only other way of grouping attributes that I can think of is inheritance, but firstly, inheritance is bad because you can't inherit from some other class, and secondly, it will only work if the attributes have attribute usage inherit set to true
ContactFrequently Asked QuestionsJoin The DiscordBugs & Feature RequestsTerms & Privacy