如何在asp.net mvc中访问查询字符串参数?

时间:2009-02-27 08:53:09

标签: asp.net-mvc query-string

我希望在我的视图中应用不同的排序和过滤 我想我将通过查询字符串传递排序和过滤 params

@Html.ActionLink("Name", "Index", new { SortBy= "Name"})

这种简单的结构允许我排序。 View在查询字符串中返回:

?SortBy=Name

现在我想添加过滤,我希望我的查询字符串最终以

结束
?SortBy=Name&Filter=Something

如何在ActionLink中添加其他参数到已存在的参数列表?例如:

user requests /Index/

查看

 @Html.ActionLink("Name", "Index", new { SortBy= "Name"})

 @Html.ActionLink("Name", "Index", new { FilterBy= "Name"})

链接:第一个看起来像/Index/?SortBy=Name,第二个看起来是/Index/?FilterBy=Name

我希望当用户按下排序链接后他应用了一些过滤 - 过滤不会丢失,所以我需要一种方法来组合我的参数。 我的猜测是应该有一种方法来解析查询字符串,但从某些MVC对象中获取参数集合。

5 个答案:

答案 0 :(得分:29)

到目前为止,我想出的最佳方法是创建ViewContext.RouteData.Values的副本 并将QueryString值注入其中。 然后在每次使用ActionLink之前修改它。 仍试图弄清楚如何使用.Union()而不是一直修改字典。

<% RouteValueDictionary   tRVD = new RouteValueDictionary(ViewContext.RouteData.Values); %>

<% foreach (string key in Request.QueryString.Keys )
    {
         tRVD[key]=Request.QueryString[key].ToString();
    } %>

<%tRVD["SortBy"] = "Name"; %>
                <%= Html.ActionLink("Name", "Index", tRVD)%>

答案 1 :(得分:12)

我的解决方案类似于qwerty1000。我创建了一个扩展方法ActionQueryLink,它采用与标准ActionLink相同的基本参数。它循环遍历Request.QueryString并将找到的所有参数添加到RouteValues字典中但尚未存在(因此我们可以根据需要覆盖原始查询字符串)。

要保留现有字符串但不添加任何键,用法为:

<%= Html.ActionQueryLink("Click Me!","SomeAction") %>

要保留现有字符串并添加新密钥,用户将:

<%= Html.ActionQueryLink("Click Me!","SomeAction", new{Param1="value1", Param2="value2"} %>

以下代码适用于两种用法,但根据需要添加其他重载以匹配其他ActionLink扩展名应该非常容易。

    public static string ActionQueryLink(this HtmlHelper htmlHelper,
        string linkText, string action)
    {
        return ActionQueryLink(htmlHelper, linkText, action, null);
    }

    public static string ActionQueryLink(this HtmlHelper htmlHelper, 
        string linkText, string action, object routeValues)
    {
        var queryString =
            htmlHelper.ViewContext.HttpContext.Request.QueryString;

        var newRoute = routeValues == null 
            ? htmlHelper.ViewContext.RouteData.Values 
            : new RouteValueDictionary(routeValues);

        foreach (string key in queryString.Keys)
        {
            if (!newRoute.ContainsKey(key)) 
                newRoute.Add(key, queryString[key]);
        }
        return HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext,
            htmlHelper.RouteCollection, linkText, null /* routeName */, 
            action, null, newRoute, null);
    }

答案 2 :(得分:8)

<%= Html.ActionLink("Name", "Index", new { SortBy= "Name", Filter="Something"}) %>

要保留查询字符串,您可以:

<%= Html.ActionLink("Name", "Index", 
     String.IsNullOrEmpty(Request.QueryString["SortBy"]) ? 
        new { Filter = "Something" } : 
        new { SortBy=Request.QueryString["SortBy"], Filter="Something"}) %>

或者,如果您有更多参数,则可以使用Request.QueryString来手动构建链接。

答案 3 :(得分:4)

使用ActionLinkCombined代替ActionLink

        public static string ActionLinkCombined(this HtmlHelper htmlHelper, string linkText, string actionName,
                                            object routeValues)
    {
        var dictionary = new RouteValueDictionary();
        foreach (var pair in htmlHelper.ViewContext.Controller.ValueProvider)
            dictionary[pair.Key] = pair.Value.AttemptedValue;
        if (routeValues != null)
        {
            foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(routeValues))
            {
                object o = descriptor.GetValue(routeValues);
                dictionary[descriptor.Name] = o;
            }
        }
        return htmlHelper.ActionLink(linkText, actionName, dictionary);
    }

答案 4 :(得分:2)

<强> MVC4

@Html.ActionLink("link text","action",new { @id = 5, @name = "textName", @abc = "abc" })

 @Html.ActionLink("link text", "action", "controller", new { @id = 5, @name = "textName", @abc = "abc" }, new { @class = "cssClass" })

querystring就像:

yourDomainRout/action/5?name=textName&abc=abc

它会有class="cssClass"