【问题标题】:MVC ActionLink add all (optional) parameters from current urlMVC ActionLink 从当前 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") %>

【问题讨论】:

    标签: c# asp.net asp.net-mvc actionlink routevalues


    【解决方案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:你可以用&lt;%= Html.CustomLink("Foo") %&gt; 来称呼它。附: @Muhammad - 所有的 txt spk 是怎么回事?你知道,我们不限于 160 个字符!
        • 我需要更多关于这件事的信息,我不明白。有些文章可能会有所帮助。错误:“System.Web.Mvc.HtmlHelper”不包含“ActionLinkwParams”的定义,并且没有扩展方法“ActionLinkwParams”接受类型为“System.Web.Mvc.HtmlHelper' 可以找到(您是否缺少 using 指令或程序集引用?
        • 啊抱歉请用字符串代替 MvcHtmlString
        • 另外你需要在你的 veiw 中添加命名空间以使用自定义 html 帮助器请stackoverflow.com/questions/1105276/… 了解更多详细信息
        猜你喜欢
        • 1970-01-01
        • 2011-11-11
        • 2015-02-21
        • 2012-01-23
        • 1970-01-01
        • 2013-07-16
        • 1970-01-01
        • 2013-04-08
        • 1970-01-01
        相关资源
        最近更新 更多