OrElse
OrElse

Reputation: 9959

Mvc routing. How can i set a default parameter in .net core 3.0?

My controller is

public partial class GridController : Controller
{
      [Route("/grid/{name}")]
      public IActionResult Index(string name)
      {

      }
}

Routing is setup correctly since if i visit /grid/something i get http ok.

But how can i set a default parameter in startup.cs?

I tried the following but on page load, i get http 404 error

endpoints.MapControllerRoute(
                   "default",
                   "{controller=Grid}/{action=Index}/{name}");

Upvotes: 0

Views: 1752

Answers (4)

Andrius R.
Andrius R.

Reputation: 189

First of all, you did not specify the name parameter in your endpoint configuration. So it should have been {controller=Grid}/{action=Index}/{name=something}. But if there are overloads, this does not seem to work anyway. I wonder if this is a bug or is it intended by design. It seems that if there is are multiple overloads of the same action, execution gets directed to the parameterless one.

Here's another workaround with the possibility to use parameters. I tried this with .NET Core 2.2. Create a new action with the same parameters, but without RouteAttribute. From there you can do a redirect to the necessary action. Here's an example where I use TestIndex for the default route.

[Route("/[controller]/{name}/{age}")]
public IActionResult Index(string name, int age)
{
    // implementation
    return Ok($"{name} is {age} years old.");
}

public IActionResult Index()
{
    return Index("Mr. It", 7);
}

public IActionResult TestIndex(string name, int age)
{
    return RedirectToAction(nameof(Index), new { name, age });
}

Then for default route use the new method, e.g. {controller=Grid}/{action=TestIndex}/{name=That}/{age=42}.

If you use this for testing, the new action could be omitted from production by adding a TypeFilterAttribute. See this answer for more details.

Upvotes: 0

OrElse
OrElse

Reputation: 9959

Okay. Ended up with a workaround

endpoints.MapControllerRoute(
    "default",
    "{controller=Grid}/{action=Index}");

and by adding an extra action overload.

public IActionResult Index()
{
    return Index("something");
}

it simply works

[Route("/grid/{name}")]
public IActionResult Index(string name )
{
}

Upvotes: 2

bolkay
bolkay

Reputation: 1909

In your route template. The name parameter is not optional.

So, use {name?}.

Upvotes: 1

Satya
Satya

Reputation: 26

Use attribute routing at Controller level, So that it will be applicable to all the action method under that controller.

Upvotes: 0

Related Questions