Johan Herstad
Johan Herstad

Reputation: 692

How to generate a link from controller to razorpages?

I need to create a link of type string from my mvc controller to a razor page. Asp.Net Core 2.2. I use IUrlHelper:

int number = 4;
string callbackUrl = Url.Page(
   "/Test/Name",
   pageHandler: null,
   values: new { number },
   protocol: Request.Scheme);

the callbackUrl is null. This works from the razor pages code behind, but not from a controller. From the controller the UrlHelper inherits from ControllerBase and from razor PageModel, so there are two different implementations. But how could I get the controller urlhelper to work so that I can create a razorpages link?

(Another, slightly different issue, is how to generate links like this from class libraries outside controllers in a good way?).

Upvotes: 5

Views: 5625

Answers (2)

poke
poke

Reputation: 387547

I cannot reproduce your problem. I have this code inside of an MVC controller, which is the exact same code to generate the URL that’s shown in the question:

public IActionResult Test()
{
    int number = 4;
    string callbackUrl = Url.Page(
        "/Test/Name",
        pageHandler: null,
        values: new { number },
        protocol: Request.Scheme);

    return Json(new
    {
        callbackUrl
    });
}

In addition, I have a Razor page at /Pages/Test/Name.cshtml with the following contents:

@page "{number}"
Hello @RouteData.Values["number"]!

Note the specification of the route parameter number, which matches the route parameter given in the Url.Page call within the controller.

If I run that application and open up http://localhost:5000/Home/Test, then I get the following response which is exactly what I expect to get generated:

{"callbackUrl":"http://localhost:5000/Test/Name/4"}

If you are seeing null instead, chances are that the route value number does not match the parameter within your Razor page. In that case, the routing does not find a matching Razor page.

If you have an unparameterized Razor page (i.e. just @page without an argument), the the response from the MVC action should be the following where the route value is provided as a query argument:

{"callbackUrl":"http://localhost:5000/Test/Name?number=4"}

Instead of the UrlHelper, which depends on ambient values and as such is best used within controller actions or Razor views, you can also use the new LinkGenerator. The LinkGenerator will generally give you the same experience as the UrlHelper but does not require an ambient setup, so it can be used in the same way regardless of where you actually are.

Upvotes: 3

Darkseal
Darkseal

Reputation: 9564

ASP.NET Core 2.2 introduced the new LinkGenerator service, a singleton that can be called outside the context of a HTTP call in order to generate a URL string.

Example:

public class SampleController : ControllerBase
{
  protected readonly LinkGenerator _linkGenerator;
  / ...

(and then, in the action method):

return _linkGenerator.GetPathByAction(
     httpContext,
     controller: "Home",
     action: "Index",
     values: new { id=1 });

Upvotes: 1

Related Questions