asp.net - 如何使用 Html.ActionLink 覆盖路由表默认值?

标签 asp.net asp.net-mvc-3 razor asp.net-mvc-routing actionlink

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
        );

这是我的操作链接

        @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
<小时/>

---编辑--- 抱歉,这是操作

        public ActionResult Machine(string id, DateTime filterDate, string filterLevel)
        {
...
            var model = new LogListViewModel { LogEntries = logEntries };
            return View(model);
        }
<小时/>

对于赏金,我想知道如何覆盖 global.asax 路由中指定的“默认”值。即我希望能够覆盖filterLevel和filterDate。

最佳答案

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 解决方案的原因是它可能是重复的。由于您只有一条路线,因此这些参数可能表示全局功能,而不是操作范围的功能。您可以通过在每个 Controller 上的操作过滤器中添加值来解决此问题,或者您可以使用自定义路由处理程序来全局应用此问题。其中任何一个都允许您将 filterLevelfilterDate 字段从您的路由定义中取出,并且仍然获得您想要的范围。那么使用 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);
    }
}

关于asp.net - 如何使用 Html.ActionLink 覆盖路由表默认值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4865608/

相关文章:

c# - 如何像 Vue 一样从父层向 Blazor 组件随机添加 CSS 属性?

c# - 我们如何处理 IIS 上 ASP.NET MVC 应用程序的异常

Javascript、Razor 和 Escape 字符。像撇号

c# - 限制 ReportViewer 控件中下拉列表的选项

asp.net-mvc-3 - Glimpse HUD 和 SQL 选项卡中的数据库查询计数之间存在差异

multithreading - Unity MVC GetService在后台线程抛出NullReferenceException

c# - ActionResult 的不同结果

c# - 名称 'Scripts' 在 MVC 的当前上下文中不存在

c# - Response.Addheader 刷新导致 404 错误

c# - 为什么按钮事件函数在 ASP.NET 中的页面重新加载期间运行?