ASP.NET Core UrlHelper and how it works
Asked Answered
R

1

26

I'm rather new to ASP.NET Core, and right now I am trying to get a grasp on how UrlHelper works in general.

In my controller, I want to create an absolute URL to another action in the same controller, e.g. http://localhost:PORT/api/controller/action. The question is now, how do I do it?

I have tried with the following:

var urlHelper = new UrlHelper(new ActionContext());
var url = urlHelper.Action("ACTION", "CONTROLLER");

Furthermore, what are those different contexts like ActionContext?

Redeemer answered 27/9, 2018 at 12:24 Comment(0)
R
59

You really shouldn’t create a UrlHelper yourself. It’s likely that whatever context you are currently in, there is already an IUrlHelper instance available:

So chances are, that you can just access this.Url to get an URL helper.

If you find yourself in a situation where that does not exist, for example when implementing your own service, then you can always inject a IUrlHelperFactory together with the IActionContextAccessor to first retrieve the current action context and then create an URL helper for it.

As for what that ActionContext is, it is basically an object that contains various values that identify the current MVC action context in which the current request is being handled. So it contains information about the actual request, the resolved controller and action, or the model state about the bound model object. It is basically an extension to the HttpContext, also containing MVC-specific information.


If you are running ASP.NET Core 2.2 or later, you can also use the LinkGenerator instead of the IUrlHelper inside your services which gives you an easier way to generate URLs compared to having to construct the helper through the IUrlHelperFactory.

Rosendorosene answered 27/9, 2018 at 12:38 Comment(3)
In Startup.ConfigureServices I need to set LoginPath option of services.ConfigureApplicationCookie... so I'm not in any page or view.. In this case UrlHelper is not available and LinkGenerator is an abstract class. Using hardcoded strings seems to work most of the time, but not for all environments. Looks like we have to add configuration for this?Wastebasket
@LouisSomers You can use DI-based configuration for this: services.AddOptions<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme).Configure<LinkGenerator>((options, generator) => { options.LoginPath = generator.GetPathByAction(…); }) – If you cannot get that to work, feel free to create a new question and link to it here.Rosendorosene
Thanks, I tried injecting but but I now get the exception System.InvalidOperationException: 'Unable to resolve service for type 'Microsoft.AspNetCore.Routing.LinkGenerator' while attempting to activate 'MyApp.Startup'.'. Maybe you can add an answer to this question since app.UsePathBase() does not seem to be the full answer (it does not automagically change hard-coded "~/..." paths). What about static or default values like in public IActionResult Login(string returnUrl = "~/"){...}Wastebasket

© 2022 - 2024 — McMap. All rights reserved.