MVC ActionLink从当前url添加所有(可选)参数

非常有名的ActionLink

   

现在,此链接位于我的详细信息视图中。 索引视图是搜索页面。 其URL如下所示:

 http://localhost:50152/2011-2012/Instelling/Details/76?gemeente=Dendermonde&postcode=92**&gebruikerscode=VVKSO114421&dossiernr=114421%20&organisatie=CLB 

如您所见,相当多的参数。 显然我想在返回Index页面时保留所有这些参数,所以我需要在ActionLink添加它们。

现在,我已经厌倦了手动操作,它可以1,但不适用于6.这应该会更容易。

问题:如何将当前URL的所有参数作为可选的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:

   

我最好把这段代码放在哪里? 不在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; } } }  ...  

这就是我最终解决它的方式,我很自豪,因为它工作得非常好而且非常干燥。

视图中的调用:

  <%: Html.ActionLinkwParams("Back to List", "Index")%> 

但是有了重载,它可以是普通ActionLink所采用的任何东西。

帮助者:

帮助程序从URL中获取不在路径中的所有参数。 例如:这个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我有paramters postalCode有一些价值。 我的代码在URL中获取所有这些代码,通过将其设置为string.Empty,我从列表中删除此参数。

欢迎评论或想法优化它。

为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; } } } 

要在视图中使用扩展方法,请参阅此问题和答案: 如何在ASP.NET MVC视图中使用扩展方法?

这比接受的答案更简单,代码少得多。

这是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 { ///  /// 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. ///  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 { { "class", "page-link" } }) 

如果请求URL中不存在Page参数,则会将其添加到生成的URL中。 如果确实存在,则其值将更改为5。

本文对我的解决方案有更详细的解释。

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

我测试了这个和它的工作。 可以从查询字符串HTH获取可选参数

也许最好的方法是在遍历前一个路由值字典的地方编写自己的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 }