在 asp.net mvc 中使用多个可选参数进行路由
Routing in asp.net mvc with multiple optional parameters
我正在开发一个 asp.net mvc 4 应用程序,我需要一个自定义路由来处理多个参数,如下所示:
routes.MapRoute(
"Default",
"FilteredResults/Filter1-{1stParam}/Filter2-{2ndParam}/..../Filter-N{nthParam}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } defaults
);
我希望能够仅将参数的子集传递给路由(取决于是否选择了某些过滤器)
例如,如果我只选择了第二个过滤器,我想这样引用它:
<a href="/FilteredResults/Filter2-1000">
是否可以在单个路由中执行此操作而无需为每个过滤器组合创建大量路由?
你可以试试下面的例子
在 RouteConfig 上:
routes.MapRoute("Name", "tag/{*tags}", new { controller = ..., action = ... });
在控制器上:
ActionResult MyAction(string tags) {
foreach(string tag in tags.Split("/")) {
...
}
}
您可以创建一个 custom RouteBase 实现来处理这个细节。
public class FilteredRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
var path = httpContext.Request.Path;
// Path always starts with a "/", so ignore it.
var segments = path.Substring(1).Split('/');
if (segments.Any() && segments[0].Equals("FilteredResults", StringComparison.OrdinalIgnoreCase))
{
var result = new RouteData(this, new MvcRouteHandler());
result.Values["controller"] = "Filter";
result.Values["action"] = "ProcessFilters";
// Add filters to route data (skip the first segment)
var filters = segments.Skip(1).ToArray();
foreach (var filter in filters)
{
string key = ParseRouteKey(filter);
var value = ParseRouteValue(filter);
result.Values[key] = value;
}
}
// Make sure to return null if this route does not match
return result;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
VirtualPathData result = null;
// Process outgoing route here (to rebuild the URL from @Html.ActionLink)
return result;
}
}
请注意,如果您这样做,过滤器的提供顺序无关紧要,只要 URL 以 /FilteredResults/
开头。
然后你只需像这样将它添加到你的路由配置中。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Add the filtered route
routes.Add("Filtered", new FilteredRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
我正在开发一个 asp.net mvc 4 应用程序,我需要一个自定义路由来处理多个参数,如下所示:
routes.MapRoute(
"Default",
"FilteredResults/Filter1-{1stParam}/Filter2-{2ndParam}/..../Filter-N{nthParam}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } defaults
);
我希望能够仅将参数的子集传递给路由(取决于是否选择了某些过滤器)
例如,如果我只选择了第二个过滤器,我想这样引用它:
<a href="/FilteredResults/Filter2-1000">
是否可以在单个路由中执行此操作而无需为每个过滤器组合创建大量路由?
你可以试试下面的例子
在 RouteConfig 上:
routes.MapRoute("Name", "tag/{*tags}", new { controller = ..., action = ... });
在控制器上:
ActionResult MyAction(string tags) {
foreach(string tag in tags.Split("/")) {
...
}
}
您可以创建一个 custom RouteBase 实现来处理这个细节。
public class FilteredRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
RouteData result = null;
var path = httpContext.Request.Path;
// Path always starts with a "/", so ignore it.
var segments = path.Substring(1).Split('/');
if (segments.Any() && segments[0].Equals("FilteredResults", StringComparison.OrdinalIgnoreCase))
{
var result = new RouteData(this, new MvcRouteHandler());
result.Values["controller"] = "Filter";
result.Values["action"] = "ProcessFilters";
// Add filters to route data (skip the first segment)
var filters = segments.Skip(1).ToArray();
foreach (var filter in filters)
{
string key = ParseRouteKey(filter);
var value = ParseRouteValue(filter);
result.Values[key] = value;
}
}
// Make sure to return null if this route does not match
return result;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
VirtualPathData result = null;
// Process outgoing route here (to rebuild the URL from @Html.ActionLink)
return result;
}
}
请注意,如果您这样做,过滤器的提供顺序无关紧要,只要 URL 以 /FilteredResults/
开头。
然后你只需像这样将它添加到你的路由配置中。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Add the filtered route
routes.Add("Filtered", new FilteredRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}