Global.asax路线值
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional, filterDate = DateTime.Now.AddDays(-1), filterLevel = "INFO" } // Parameter defaults
);
这是我的actionlink
@Html.ActionLink(item.MachineName, "Machine", new { id = item.MachineName, filterLevel = "hello" }, null)
当在actionlink中指定filterlevel时,它会生成一个这样的URL:
http://localhost:1781/LoggingDashboard/log/level/VERBOSE
这是我目前所在的页面。如果我更改actionlink以使用除路由表中具有默认值的属性之外的属性(是的,如果我使用filterDate它也会混乱),它会生成如下链接:
@Html.ActionLink(item.MachineName, "Machine", new { id = item.MachineName, foo = "bar" }, null)
http://localhost:1781/LoggingDashboard/log/Machine/C0UPSMON1?foo=bar
这种行为是否正确?我是否应该无法覆盖路由表中设置的默认值?我已经确认,如果我从路由表中删除filterLevel默认值,这可以正常工作:
http://localhost:1781/LoggingDashboard/log/Machine/C0UPSMON1?filterLevel=VERBOSE
--- --- EDIT 对不起,这是行动
public ActionResult Machine(string id, DateTime filterDate, string filterLevel)
{
...
var model = new LogListViewModel { LogEntries = logEntries };
return View(model);
}
对于赏金,我想知道如何覆盖从global.asax路由中指定的“默认”值。即我希望能够覆盖filterLevel和filterDate。
答案 0 :(得分:3)
SLaks已经说过可能是处理这个问题的最佳方法。我不知道这是否有效,但是,如果你把它放在现有路线之上会发生什么(所以你的global.asax现在会有两个)?
routes.MapRoute(
"Filtered",
"{controller}/{action}/{id}?filterLevel={filterLevel}&filterDate={filterDate}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional,
filterDate = DateTime.Now.AddDays(-1),
filterLevel = "INFO"
}
);
另外,我刚想到你不喜欢SLaks解决方案的原因是它可能是重复的。由于您只有一个路由,因此这些参数可能表示全局功能,而不是动作范围的功能。您可以通过在每个控制器上的操作过滤器中添加值来解决此问题,或者您可以使用自定义路由处理程序来全局应用此值。这些中的任何一个都允许您从路径定义中取出filterLevel
和filterDate
字段,并仍然可以获得所需的范围。那么在Html.ActionLink()
的查询字符串中传递参数应该没问题。
要使用路由处理程序执行此操作,请将路由定义更改为:
routes.Add(
new Route(
"{controller}/{action}/{id}",
new RouteValueDictionary(new{ controller = "Home", action = "Index", id = UrlParameter.Optional}),
new CustomRouteHandler()));
您对路由处理程序的实现将是这样的:
public class CustomRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var routeValues = requestContext.RouteData.Values;
if(!routeValues.ContainsKey("filterLevel"))
{
routeValues.Add("filterLevel","INFO");
}
if(!routeValues.ContainsKey("filterDate"))
{
routeValues.Add("filterDate", DateTime.Now.AddDays(-1));
}
var mvcRouteHandler = new MvcRouteHandler();
return (mvcRouteHandler as IRouteHandler).GetHttpHandler(requestContext);
}
}
答案 1 :(得分:1)
我认为默认值始终是URL中定义的条目,您无法定义默认值以省略核心URL中没有的内容,而其他任何内容都作为查询字符串传递。
有趣的问题。
HTH。
答案 2 :(得分:1)
您应该在方法中指定默认值,如下所示:
public ActionResult Machine(string id, DateTime? filterDate = null, string filterLevel = "INFO")
{
filterDate = filterDate ?? DateTime.Now.AddDays(-1);
var model = new LogListViewModel { LogEntries = logEntries };
return View(model);
}
答案 3 :(得分:1)
如果在URL模式中指定了不的默认值,则无法覆盖它们,因为它们用于在匹配URL生成路由时确定路由选择。
让我举个例子。假设你有以下两条路线。
routes.MapRoute(
"Default1", // Route name
"foo/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional
, filterLevel = "INFO" } // Parameter defaults
);
routes.MapRoute(
"Default2", // Route name
"bar/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional
, filterLevel = "DEBUG" } // Parameter defaults
);
请注意,“filterLevel”有一个默认值,但URL模式中没有“{filterLevel}”参数。
执行此操作时应匹配哪个网址?
@Html.ActionLink(item.MachineName, "Machine",
new { id = item.MachineName, filterLevel = "RANDOM" }, null)
如果你可以覆盖filterLevel的默认值,那么你希望两个路由都匹配。但这没有意义。在这种情况下,两者都不匹配,因为filterLevel不在URL模式中,因此提供的filterLevel必须与默认值匹配。这样,你可以这样做:
@Html.ActionLink(item.MachineName, "Machine",
new { id = item.MachineName, filterLevel = "INFO" }, null)
//AND
@Html.ActionLink(item.MachineName, "Machine",
new { id = item.MachineName, filterLevel = "DEBUG" }, null)
分别生成第一条和第二条路线的URL。
这种混淆是我总是向always use named routes推荐的原因。