简体   繁体   中英

Routing using a named parameter in the request URL

I'm trying to navigate to the route /Account/UserProfile/{username} , but I'm not sure that I've configured the routes correctly. Or rather, I'm not sure what to add to the route table to make this route work.

Here's the action method:

public IActionResult UserProfile(string username)
{
    // Do something
}

Which is a simple GET method that I'm hitting correctly. My problem is that even though I supply a string in the url, like: /Account/UserProfile/MyUsername , the string MyUsername is not being sent to my controller.

I only have the standard route already added when creating the application. What do I need to add to allow these routes to work?

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

The value will be in the RouteData under the username key, but it won't be mapped to the parameter named username automatically, because the key isn't a known route value containing that parameter name.

You can create a route just for this method:

routes.MapRoute(
    name: "userProfileByUsername",
    template: "Account/UserProfile/{username}"),
    defaults: new { controller = "Account", action = "UserProfile" });

But that would be nonsense, as it would require creating a route for every action method. When a pattern of multiple uses for a single route emerges, it pays off to create a route like this, because it saves you from having to declare the same attribute multiple times.

For example when you want to declare multiple action methods in one controller:

  • /Account/UserProfile/{username}
  • /Account/View/{username}
  • /Account/Foo/{username}
  • /Account/Bar/{username}

Then it would be smart to create a new route instead:

routes.MapRoute(
    name: "accountActionByUsername",
    template: "Account/{action}/{username}"),
    defaults: new { controller = "Account" });

For a one-off case, or when the pattern differs per action method, you could use attribute routing to opt-in to specific routes:

[HttpGet("[action]/{username}"]
public IActionResult UserProfile(string username)

Note the use of the new [action] placeholder , so you won't have to have your action name in a string anymore.

Or you could find the value by accessing the raw route data , but you really shouldn't:

public IActionResult UserProfile()
{
    string username = ViewContext.RouteData.Values["username"];

    // ...
}

Finally you could opt to have the username be a query string parameter:

public IActionResult UserProfile([FromQuery]string username)

Making the request URL /Account/UserProfile?username=MyUsername .

you are missing username parameter in your route. the parameter names need to match

app.UseMvc(routes => {
    routes.MapRoute(
        name: "UserProfile",
        template: "Account/UserProfile/{username}",
        defaults: { controller = "Account", action = "UserProfile" });

    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM