MVC ActionLink 从当前 url 添加所有(可选)参数
Posted
技术标签:
【中文标题】MVC ActionLink 从当前 url 添加所有(可选)参数【英文标题】:MVC ActionLink add all (optional) parameters from current url 【发布时间】:2010-09-23 15:29:15 【问题描述】:非常有名的ActionLink
:
<%: html.ActionLink("Back to List", "Index")%>
现在,此链接位于我的详细信息视图中。索引视图是一个搜索页面。它的 URL 如下所示:
http://localhost:50152/2011-2012/Instelling/Details/76?gemeente=Dendermonde&postcode=92**&gebruikerscode=VVKSO114421&dossiernr=114421%20&organisatie=CLB
如您所见,参数数量相当多。显然我想在返回Index页面时保留所有这些参数,所以我需要在ActionLink
中添加它们。
现在,我已经厌倦了手动操作,1 可以,但 6 不行。这应该会容易得多。
问题:如何将当前网址的所有参数作为可选的RouteValues
返回到ActionLink
。
我一直在寻找Request.QueryString
。它必须与那个有关。我正在考虑在Global.asax
中编写一些静态方法来完成这项工作,但还没有运气。也许有一种我不知道的简单方法可以做到这一点?
编辑:这是我想出的(可行)
在 global.asax:
public static RouteValueDictionary optionalParamters(NameValueCollection c)
RouteValueDictionary r = new RouteValueDictionary();
foreach (string s in c.AllKeys)
r.Add(s, c[s]);
return r;
Details.aspx:
<%: Html.ActionLink("Back to List", "Index", MVC2_NASTEST.MvcApplication.optionalParamters(Request.QueryString))%>
我最好把这段代码放在哪里?不在Global.asax
我猜...
编辑 2:
using System;
using System.Web.Mvc;
namespace MVC2_NASTEST.Helpers
public static class ActionLinkwParamsExtensions
public static MvcHtmlString CustomLink(this HtmlHelper helper, string linktext)
//here u can use helper to get View context and then routvalue dictionary
var routevals = helper.ViewContext.RouteData.Values;
//here u can do whatever u want with route values
return null;
<%@ Import Namespace="MVC2_NASTEST.Helpers" %>
...
<%: Html.ActionLinkwParams("Index") %>
【问题讨论】:
【参考方案1】:这就是我最终修复它的方法,我很自豪,因为它工作得非常好而且非常干燥。
视图中的调用:
<%: Html.ActionLinkwParams("Back to List", "Index")%>
但是对于重载,它可以是普通 ActionLink 采用的任何东西。
助手:
helper 从 url 中获取所有不在路由中的参数。 例如:这个网址:
http://localhost:50152/2011-2012/myController/Details/77?postalCode=9***&org=CLB
因此,它将获取 postalCode 和 Org 并将其放置在新的 ActionLink 中。 通过重载,可以添加其他参数,并且可以删除现有 url 中的参数。
using System;
using System.Web.Mvc;
using System.Web.Routing;
using System.Collections.Specialized;
using System.Collections.Generic;
namespace MVC2_NASTEST.Helpers
public static class ActionLinkwParamsExtensions
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, string controller, object extraRVs, object htmlAttributes)
NameValueCollection c = helper.ViewContext.RequestContext.HttpContext.Request.QueryString;
RouteValueDictionary r = new RouteValueDictionary();
foreach (string s in c.AllKeys)
r.Add(s, c[s]);
RouteValueDictionary htmlAtts = new RouteValueDictionary(htmlAttributes);
RouteValueDictionary extra = new RouteValueDictionary(extraRVs);
RouteValueDictionary m = Merge(r, extra);
return System.Web.Mvc.Html.LinkExtensions.ActionLink(helper, linktext, action, controller, m, htmlAtts);
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action)
return ActionLinkwParams(helper, linktext, action, null, null, null);
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, string controller)
return ActionLinkwParams(helper, linktext, action, controller, null, null);
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, object extraRVs)
return ActionLinkwParams(helper, linktext, action, null, extraRVs, null);
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, string controller, object extraRVs)
return ActionLinkwParams(helper, linktext, action, controller, extraRVs, null);
public static MvcHtmlString ActionLinkwParams(this HtmlHelper helper, string linktext, string action, object extraRVs, object htmlAttributes)
return ActionLinkwParams(helper, linktext, action, null, extraRVs, htmlAttributes);
static RouteValueDictionary Merge(this RouteValueDictionary original, RouteValueDictionary @new)
// Create a new dictionary containing implicit and auto-generated values
RouteValueDictionary merged = new RouteValueDictionary(original);
foreach (var f in @new)
if (merged.ContainsKey(f.Key))
merged[f.Key] = f.Value;
else
merged.Add(f.Key, f.Value);
return merged;
在视图中使用重载:
<%: Html.ActionLinkwParams("Back to List", "Index","myController", new testValue = "This is a test", postalCode=String.Empty, new @class="test")%>
在 URL 中,我的参数 postalCode 具有一定的价值。我的代码将所有这些都包含在 URL 中,通过将其设置为 string.Empty,我从列表中删除了此参数。
欢迎对优化提出意见或想法。
【讨论】:
当您需要获取当前查询字符串时,对于下一页/上一页功能非常有用。为这个 +1 干杯 谢谢。我用它来排序链接。 这对我来说效果很好(在我对其进行了一些修改以重命名一些可怕的变量名之后)。 +1! 真是救命稻草,现在我知道如何创建自己的 Html 扩展方法了。竖起两个大拇指!【参考方案2】:为 Request.QueryString 创建一个 ToRouteValueDictionary() 扩展方法以按原样使用 Html.ActionLink 并简化您的视图标记:
<%: Html.ActionLink("Back to List", "Index", Request.QueryString.ToRouteValueDictionary())%>
您的扩展方法可能如下所示:
using System.Web.Routing;
using System.Collections.Specialized;
namespace MyProject.Extensions
public static class CollectionExtensions
public static RouteValueDictionary ToRouteValueDictionary(this NameValueCollection collection)
var routeValueDictionary = new RouteValueDictionary();
foreach (var key in collection.AllKeys)
routeValueDictionary.Add(key, collection[key]);
return routeValueDictionary;
要在您的视图中使用扩展方法,请参阅以下问题和答案:How do I use an extension method in an ASP.NET MVC View?
这比公认的答案更简单,涉及的代码也少得多。
【讨论】:
您是否阅读了接受的代码?它与您描述的相同,相同的代码等等。合并 url 路由值和个人添加的路由值,等等。我必须说它的效果非常好。 感谢您的评论,@Stefanvds。我确实阅读了接受的答案。它没有任何问题,但它增加了问题中没有的行为。此外,问题还问“我最好把这段代码放在哪里?”这个答案提供了使用扩展方法的选项。【参考方案3】:这是一个 ViewContext 的扩展方法,它根据请求路由值和查询字符串创建一个 RouteValueDictionary。
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyMvcApplication.Utilities
public static class ViewContextExtensions
/// <summary>
/// Builds a RouteValueDictionary that combines the request route values, the querystring parameters,
/// and the passed newRouteValues. Values from newRouteValues override request route values and querystring
/// parameters having the same key.
/// </summary>
public static RouteValueDictionary GetCombinedRouteValues(this ViewContext viewContext, object newRouteValues)
RouteValueDictionary combinedRouteValues = new RouteValueDictionary(viewContext.RouteData.Values);
NameValueCollection queryString = viewContext.RequestContext.HttpContext.Request.QueryString;
foreach (string key in queryString.AllKeys.Where(key => key != null))
combinedRouteValues[key] = queryString[key];
if (newRouteValues != null)
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(newRouteValues))
combinedRouteValues[descriptor.Name] = descriptor.GetValue(newRouteValues);
return combinedRouteValues;
您可以将创建的 RouteValueDictionary 传递给 Html.ActionLink 或 Url.Action
@Html.ActionLink("5", "Index", "Product",
ViewContext.GetCombinedRouteValues(new Page = 5 ),
new Dictionary<string, object> "class", "page-link" )
如果请求 URL 中不存在 Page 参数,则会在生成的 URL 中添加该参数。如果确实存在,则其值将更改为 5。
This article对我的解决方案有更详细的解释。
【讨论】:
【参考方案4】:public static class Helpers
public static MvcHtmlString CustomLink(this HtmlHelper helper,string LinkText, string actionName)
var rtvals = helper.ViewContext.RouteData.Values;
var rtvals2 = helper.RouteCollection;
RouteValueDictionary rv = new RouteValueDictionary();
foreach (string param in helper.ViewContext.RequestContext.HttpContext.Request.QueryString.AllKeys)
rv.Add(param, helper.ViewContext.RequestContext.HttpContext.Request.QueryString[param]);
foreach (var k in helper.ViewContext.RouteData.Values)
rv.Add(k.Key, k.Value);
return helper.ActionLink(LinkText, actionName, rv);
我已经对此及其工作进行了测试。可选参数可以从查询字符串中获取 高温
【讨论】:
【参考方案5】:也许最好的方法是编写自己的 html 帮助程序,在其中遍历之前的路由值字典并将路由值添加到当前操作链接,但操作参数偏离路线。
编辑: 您可以像这样编写 html 助手:
public static MvcHtmlString CustomLink(this HtmlHelper helper,string linktext)
//here you can use helper to get View context and then routvalue dictionary
var routevals = helper.ViewContext.RouteData.Values;
//here you can do whatever you want with route values
【讨论】:
RouteValueDictionary 正是我所需要的。但是你会怎么做那个助手呢? @Stefanvds:你可以用<%= Html.CustomLink("Foo") %>
来称呼它。附: @Muhammad - 所有的 txt spk 是怎么回事?你知道,我们不限于 160 个字符!
我需要更多关于这件事的信息,我不明白。有些文章可能会有所帮助。错误:“System.Web.Mvc.HtmlHelper以上是关于MVC ActionLink 从当前 url 添加所有(可选)参数的主要内容,如果未能解决你的问题,请参考以下文章
每日踩坑 2018-11-26 MVC Razor ActionLink 生成的URL中多生成了一个参数 ?length=n
将 Css 类添加到 ASP.NET MVC 的 ActionLink
为啥 T4MVC 尝试从 Html.ActionLink 运行控制器动作?
在 ASP.NET MVC Html.ActionLink 中包含锚标记