使用 ASP.NET MVC 进行多参数路由

Posted

技术标签:

【中文标题】使用 ASP.NET MVC 进行多参数路由【英文标题】:Routing with Multiple Parameters using ASP.NET MVC 【发布时间】:2011-01-15 19:57:41 【问题描述】:

我们公司正在为我们的产品开发 API,我们正在考虑使用 ASP.NET MVC。在设计 API 时,我们决定使用如下调用,让用户从 API 请求 XML 格式的信息:

http://ws.audioscrobbler.com/2.0/?method=artist.getimages&artist=cher&api_key=b25b959554ed76058ac220b7b2e0a026

如您所见,传递了多个参数(即artistapi_key)。在 ASP.NET MVC 中,artist 将是 controllergetImages 操作,但我如何将多个参数传递给操作?

这甚至可以使用上面的格式吗?

【问题讨论】:

【参考方案1】:

通过简单地将参数添加到您的操作方法中,MVC 直接支持参数。给定如下操作:

public ActionResult GetImages(string artistName, string apiKey)

当给定如下 URL 时,MVC 将自动填充参数:

/Artist/GetImages/?artistName=cher&apiKey=XXX

另一种特殊情况是名为“id”的参数。任何名为 ID 的参数都可以放入路径而不是查询字符串中,例如:

public ActionResult GetImages(string id, string apiKey)

将使用如下所示的 URL 正确填充:

/Artist/GetImages/cher?apiKey=XXX

另外,如果你有更复杂的场景,你可以自定义 MVC 用来定位动作的路由规则。您的 global.asax 文件包含可以自定义的路由规则。默认情况下,规则如下所示:

routes.MapRoute(
            "Default",                                              // Route name
            "controller/action/id",                           // URL with parameters
            new  controller = "Home", action = "Index", id = ""   // Parameter defaults
        );

如果你想支持像

这样的 url
/Artist/GetImages/cher/api-key

您可以添加如下路线:

routes.MapRoute(
            "ArtistImages",                                              // Route name
            "controller/action/artistName/apikey",                           // URL with parameters
            new  controller = "Home", action = "Index", artistName = "", apikey = ""   // Parameter defaults
        );

和上面第一个例子一样的方法。

【讨论】:

我正在使用 .NET 4 和 MVC。我只能在路径中传递一个参数。这个 URL controller/action/artistName/apikey 没有映射到我的 2 个参数,而只是触发了 404 错误。据我所知,您只能在路径中传递 1 个参数。我做错了什么? @DavidHyogo - 我遇到了同样的问题。无论出于何种原因,即使我指定了默认操作,我也必须将我想要的操作实际放入我的 html 链接中,而不仅仅是控制器和参数。 @DavidHyogo:我遇到了同样的问题,发现您的路由模板参数必须与操作方法参数名称完全匹配,例如对于定义为 controller/action/artistName/apikey 的路由,操作方法应具有签名 public ActionResult MyMethod(string artistName, string apikey) 另外,请确保您的 URL 在到达您的自定义路由之前没有被默认路由捕获。它将根据您定义它们的方式使用第一个匹配项。在我的例子中,我试图使用路由“MyController/year/month”作为默认索引,但路由 controller/action/id 与我的 URL 匹配(MyController/2015 /04),所以我得到了 404,因为不存在名称为 2015 的操作。将我的自定义路线移到顶部解决了问题。 routeconfig 中的参数名称与我的 Action 签名不匹配,这就是它不起作用的原因,我按照@dotnetguy 描述的步骤操作,它起作用了【参考方案2】:

您可以通过查询字符串传递任意参数,但您也可以设置自定义路由以 RESTful 方式处理它:

http://ws.audioscrobbler.com/2.0/?method=artist.getimages&artist=cher&
                                  api_key=b25b959554ed76058ac220b7b2e0a026

可能是:

routes.MapRoute(
    "ArtistsImages",
    "ws/artists/artist/action/*apikey",
    new  ws = "2.0", controller="artists" artist = "", action="", apikey="" 
    );

所以如果有人使用以下路线:

ws.audioscrobbler.com/2.0/artists/cher/images/b25b959554ed76058ac220b7b2e0a026/

它会将它们带到您的示例查询字符串所做的相同位置。

以上只是一个示例,并未应用您必须设置的业务规则和约束,以确保人们不会“破解”该 URL。

【讨论】:

【参考方案3】:

从 MVC 5 开始,您还可以使用属性路由将 URL 参数配置移动到您的控制器。

这里有详细的讨论: http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx

总结:

首先你启用属性路由

 public class RouteConfig 
 
     public static void RegisterRoutes(RouteCollection routes)
     
         routes.IgnoreRoute("resource.axd/*pathInfo");

         routes.MapMvcAttributeRoutes();
      
 

然后你可以使用属性来定义参数和可选的数据类型

public class BooksController : Controller

    // eg: /books
    // eg: /books/1430210079
    [Route("books/isbn?")]
    public ActionResult View(string isbn)

【讨论】:

ASP.NET Core MVC 中的属性路由在docs.microsoft.com/en-us/aspnet/core/mvc/controllers/…进行了描述

以上是关于使用 ASP.NET MVC 进行多参数路由的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 maproute 在 asp.net mvc 中路由多个参数

ASP.NET MVC 5 中的路由可选参数

ASP.NET MVC Beta 路由、控制器操作、参数和 ActionsLinks...把它们放在一起

asp.net mvc5 action多个参数

ASP.NET MVC 2 中带有约束的可选路由参数?

asp.net mvc怎样传递多个url参数