Как получить доступ к параметрам строки запроса в asp.net mvc? - PullRequest
39 голосов
/ 27 февраля 2009

Я хочу, чтобы на мой взгляд применялись различные сортировки и фильтрации Я решил, что передам сортировку и фильтрацию 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 ]

29 голосов
/ 27 февраля 2009

до сих пор лучший способ, который я понял, это создать копию 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)%>
12 голосов
/ 22 января 2010

Мое решение похоже на 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);
    }
8 голосов
/ 27 февраля 2009
<%= 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.

4 голосов
/ 09 сентября 2009

Используйте 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);
    }
2 голосов
/ 04 февраля 2014

MVC4

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

OR

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

строка запроса будет выглядеть так:

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

было бы class="cssClass"

...