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

C# MVC ActionLink从当前url添加所有(可选)参数,c#,asp.net,asp.net-mvc,actionlink,routevalues,C#,Asp.net,Asp.net Mvc,Actionlink,Routevalues,非常著名的ActionLink: <%: Html.ActionLink("Back to List", "Index")%> 如您所见,参数的数量相当大。显然,我希望在返回索引页面时保留所有这些参数,因此我需要将它们添加到ActionLink中 现在,我已经厌倦了手动操作,1可以,但6不行。这应该会容易得多 问题:如何将当前URL的所有参数作为可选routeValue返回到ActionLink中 我一直在寻找Request.QueryString。一定是跟这个有关。我正在考虑在

非常著名的
ActionLink

 <%: Html.ActionLink("Back to List", "Index")%>
如您所见,参数的数量相当大。显然,我希望在返回索引页面时保留所有这些参数,因此我需要将它们添加到
ActionLink

现在,我已经厌倦了手动操作,1可以,但6不行。这应该会容易得多

问题:如何将当前URL的所有参数作为可选
routeValue
返回到
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;
    }
    <%: Html.ActionLink("Back to List", "Index", MVC2_NASTEST.MvcApplication.optionalParamters(Request.QueryString))%>
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") %>
    <%: Html.ActionLinkwParams("Back to List", "Index")%>
 <%: Html.ActionLinkwParams("Back to List", "Index","myController", new {testValue = "This is a test", postalCode=String.Empty}, new{ @class="test"})%>
详细信息。aspx:

    public static RouteValueDictionary optionalParamters(NameValueCollection c) {
        RouteValueDictionary r = new RouteValueDictionary();
        foreach (string s in c.AllKeys) {
            r.Add(s, c[s]);
        }
        return r;
    }
    <%: Html.ActionLink("Back to List", "Index", MVC2_NASTEST.MvcApplication.optionalParamters(Request.QueryString))%>
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") %>
    <%: Html.ActionLinkwParams("Back to List", "Index")%>
 <%: Html.ActionLinkwParams("Back to List", "Index","myController", new {testValue = "This is a test", postalCode=String.Empty}, new{ @class="test"})%>

也许最好的方法是编写自己的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
}
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;
        }
    }
}

这就是我最终修复它的方式,我很自豪,因为它工作得很好,非常干燥

视图中的调用:

    public static RouteValueDictionary optionalParamters(NameValueCollection c) {
        RouteValueDictionary r = new RouteValueDictionary();
        foreach (string s in c.AllKeys) {
            r.Add(s, c[s]);
        }
        return r;
    }
    <%: Html.ActionLink("Back to List", "Index", MVC2_NASTEST.MvcApplication.optionalParamters(Request.QueryString))%>
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") %>
    <%: Html.ActionLinkwParams("Back to List", "Index")%>
 <%: Html.ActionLinkwParams("Back to List", "Index","myController", new {testValue = "This is a test", postalCode=String.Empty}, new{ @class="test"})%>
因此,它将使用postalCode和组织并将其放置在新的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;

        }
    }

}
在使用重载的视图中:

    public static RouteValueDictionary optionalParamters(NameValueCollection c) {
        RouteValueDictionary r = new RouteValueDictionary();
        foreach (string s in c.AllKeys) {
            r.Add(s, c[s]);
        }
        return r;
    }
    <%: Html.ActionLink("Back to List", "Index", MVC2_NASTEST.MvcApplication.optionalParamters(Request.QueryString))%>
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") %>
    <%: Html.ActionLinkwParams("Back to List", "Index")%>
 <%: Html.ActionLinkwParams("Back to List", "Index","myController", new {testValue = "This is a test", postalCode=String.Empty}, new{ @class="test"})%>

在URL中,我有一些值的参数postalCode。我的代码通过将URL设置为string.Empty来获取URL中的所有参数。如果为空,我将从列表中删除此参数

欢迎对其进行优化的意见或想法

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

为Request.QueryString创建一个ToRouteValueDictionary()扩展方法,以便按原样使用Html.ActionLink并简化视图标记:

<%: Html.ActionLink("Back to List", "Index", Request.QueryString.ToRouteValueDictionary())%>
要在您的视图中使用扩展方法,请参见以下问题和答案:


这比公认的答案更简单,涉及的代码也少得多。

这里是ViewContext的扩展方法,它基于请求路由值和querystring创建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;
        }
    }
}
使用System.Collections.Specialized;
使用系统组件模型;
使用System.Linq;
使用System.Web.Mvc;
使用System.Web.Routing;
命名空间mymvcapapplication.Utilities
{
公共静态类ViewContextensions
{
/// 
///构建一个RouteValueDictionary,该Dictionary组合了请求路由值、查询字符串参数、,
///和传递的newRouteValues。来自newRouteValues的值覆盖请求路由值和查询字符串
///具有相同键的参数。
/// 
公共静态RouteValueDictionary GetCombinedRouteValues(此ViewContext ViewContext,对象newRouteValues)
{
RouteValueDictionary combinedRouteValues=新的RouteValueDictionary(viewContext.RouteData.Values);
NameValueCollection queryString=viewContext.RequestContext.HttpContext.Request.queryString;
foreach(queryString.AllKeys.Where(key=>key!=null)中的字符串键)
combinedRouteValues[key]=查询字符串[key];
if(newRouteValues!=null)
{
foreach(TypeDescriptor.GetProperties(NewRouteValue)中的PropertyDescriptor描述符)
combinedRouteValues[descriptor.Name]=descriptor.GetValue(newRouteValues);
}
返回组合路由值;
}
}
}
您可以将创建的RouteValueDictionary传递到Html.ActionLink或Url.Action

@Html.ActionLink("5", "Index", "Product",
    ViewContext.GetCombinedRouteValues(new { Page = 5 }),
    new Dictionary<string, object> { { "class", "page-link" } })
@Html.ActionLink(“5”、“索引”、“产品”,
ViewContext.GetCombinedRouteValues(新的{Page=5}),
新字典{{“类”,“页面链接”})
如果请求URL中不存在页面参数,则会将其添加到生成的URL中。如果确实存在,则其值将更改为5


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

RouteValueDictionary正是我所需要的。但是你会怎么做那个助手呢?@Stefanvds:你可以用
来称呼它。P.S.@Muhammad-这些txt spk是怎么回事?你知道,我们这里不限制160个字符!我需要更多关于这件事的信息,我不明白。有些文章可能会有所帮助。错误:“System.Web.Mvc.HtmlHelper”不包含“ActionLinkwParams”的定义,并且找不到接受类型为“System.Web.Mvc.HtmlHelper”的第一个参数的扩展方法“ActionLinkwParams”(您是否缺少using指令或程序集引用?啊,很抱歉,请使用字符串代替MvcHtmlStringplus您需要在您的视图中添加名称空间以使用自定义html帮助程序plz c了解更多详细信息您是否阅读了接受的代码?它与您描述的代码相同,代码相同,等等。合并url RouteValue和个人添加的RouteValue,等等继续。我必须说,它工作得非常好。谢谢你的评论,@Stefanvds。我确实读了被接受的答案。它没有错,但它增加了问题中没有的行为。此外,问题是“我最好把这个代码放在哪里?”此答案提供了使用扩展方法的选项。当您需要获取当前查询字符串时,下一页/上一页功能非常有用。为此,干杯+1谢谢。我正在使用它对链接进行排序。这对我来说非常有效(在我对其进行了一些修改以重命名一些可怕的变量名称后).+1!真是个救命稻草,现在我知道如何创建自己的Html扩展方法了。竖起大拇指!