使用请求URL中的命名参数进行路由

时间:2016-09-05 20:50:17

标签: c# asp.net asp.net-core asp.net-core-mvc

我尝试导航到路线/Account/UserProfile/{username},但我不确定我是否正确配置了路线。或者更确切地说,我不确定要添加到路由表中以使此路由有效。

这是行动方法:

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

这是一个我正确击中的简单GET方法。我的问题是,即使我在网址中提供了一个字符串,例如:/Account/UserProfile/MyUsername,字符串MyUsername也没有发送到我的控制器。

创建应用程序时,我只添加了标准路径。我需要添加什么才能使这些路由起作用?

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

2 个答案:

答案 0 :(得分:3)

该值将位于username键下的RouteData中,但不会自动映射到名为username的参数,因为该键不是已知的包含该参数名称的路由值。

您可以为此方法创建路线:

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

但这是无稽之谈,因为它需要为每个动作方法创建一个路径。当出现单个路径的多个用途的模式时,创建这样的路由是值得的,因为它使您不必多次声明相同的属性。

例如,当您想在一个控制器中声明多个操作方法时:

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

然后改为创建一条新路线会很聪明:

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

对于一次性案例,或者每个操作方法的模式不同,您可以使用属性路由选择加入特定路径:

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

请注意new [action] placeholder的使用,因此您不必再在字符串中使用您的操作名称了。

或者你可以通过accessing the raw route data找到值,但你真的不应该:

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

    // ...
}

最后,您可以选择将用户名作为查询字符串参数:

public IActionResult UserProfile([FromQuery]string username)

发出请求网址/Account/UserProfile?username=MyUsername

答案 1 :(得分:2)

您的路线中缺少用户名参数。参数名称需要匹配

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?}");
});