Open austins opened 5 months ago
Thanks for your feedback and suggestions!
I'm happy to add the HTTP method as a property for page routes. It wouldn't work as well for controllers since each method on a controller could potentially handle multiple HTTP methods, so I'll only be adding it to IPageRouteValues
.
I haven't decided whether I'll expose it as an HttpMethod
or string
as yet. There's no HttpMethod.Patch
in .NET Standard 2.0 which makes supporting that a little clumsy, so I'm leaning towards having it be a string
.
Regarding the relative paths, is that something you can achieve with the .Url(...)
extensions or are you wanting to get those outside the context of a request and thus don't have an IUrlHelper
instance? E.g.;
var route = Routes.Pages.Index.Get();
var path = route.Url(Url); // "/"
A method of getting the URL outside of a request is likely not something I'll include in this library because the @page
directive can be used within a razor file to make its route no longer correlate to the PageName
value—something to keep in mind with your GetPagePath
extension method. Unfortunately source generators don't have access to the output of other source generators, so I can't get route information from the output of the razor source generator to be able to determine URLs in a reliable manner at build time (without re-implementing parts of the razor source generator).
Thank you! Yeah, that sounds good. I think a string is good as long as it's the same casing as the HttpMethods constants to make comparisons easier.
For controllers, I haven't seen verb overloading done much, but you're right that it's possible. Is this how it's done in the MVC controllers?
[HttpGet("someaction")]
[HttpPost("someaction")]
public IActionResult SomeAction() { return View(); }
Would it be possible to have an array of HTTP method strings?
Update about idea 2 and the extension method I posted. I got rid of my extension method. If a route path is needed during app startup builder for configuration, IConfigureNamedOptions can be used and LinkGenerator injected there. In integration tests, I'm able to get the LinkGenerator instance from the services collection and use that with SafeRouting's Path() extension.
I opted for LinkGenerator instead of UrlHelper since that requires an action context, but I'm not too familiar with either to say if they would generate different results.
Yes, you can use any number of attributes that inherit from Microsoft.AspNetCore.Mvc.Routing.HttpMethodAttribute
to make an action handle the designated HTTP method(s). And yes, I could have a property or method yielding a collection of HTTP methods, though it's making me wonder whether the structure of controller routes should be closer to that of the page routes, e.g.; Routes.Controllers.Account_Index.Get()
instead of Routes.Controllers.Account.Index()
. That way both could conform to the same interface with an HttpMethod property returning a single value. I'm not sure that's a change I want to make at the moment though without a good use case for controllers.
That's great that you were able to use the LinkGenerator
extensions for your needs. I forgot that I added those!
I should have the HttpMethod property ready to go for page routes within the next few days. I ended up going with strongly typed rather than strings since it isn't too difficult to conditionally work around the limited API in .NET Standard 2.0.
Awesome project! Would these features be possible in the realm of source generators?
💡 Idea 1: Handler method type Assuming the handler method name conventions can't be changed in ASP.NET, if the method name starts with
OnGet
, add a property on the generated IPageRouteValues implementation, e.g.public HttpMethod Method => HttpMethod.Get;
(or the HttpMethods.Get for a string type). Same for OnPost, etc.One use case would be creating a tag helper for HTMX, which adds attributes for URLs like
hx-get
,hx-post
. The tag helper can take an attribute such ashx-for-route
and then map it to the attribute with the corresponding method along with any query/route values.💡 Idea 2 (maybe): Relative pathCurrently, there is a way to get PageName, but not the "relative path".I wrote an extension method for use outside of views. Not sure if it'll be useful within the source generated class or not. It looks like:Example mappings of page name -> relative path would be:"/Index" => "/""/Auth/Login/Index" => "/auth/login""/Admin/Posts" => "/admin/posts"