简体   繁体   English

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

[英]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. 我正在尝试导航到/Account/UserProfile/{username}路由,但不确定是否已正确配置路由。 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. 这是我正确命中的简单GET方法。 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. 我的问题是,即使我在URL中提供了一个字符串,例如: /Account/UserProfile/MyUsername ,字符串MyUsername也没有发送到我的控制器。

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. 该值将位于username密钥下的RouteData中,但不会自动映射到名为username的参数,因为该密钥不是包含该参数名的已知路由值。

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. 注意使用新的[action]占位符 ,因此您不再需要在字符串中使用动作名称。

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 . 发出请求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?}");
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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