web-dev-qa-db-ja.com

asp.net mvcのクエリ文字列パラメータにアクセスするにはどうすればよいですか?

クエリ文字列を介してソートとフィルタリングparamsを渡すことになると考えて、ビューに異なるソートとフィルタリングを適用したいと思います。

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

この単純な構造により、ソートできます。ビューはクエリ文字列でこれを返します:

?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と2番目は/Index/?FilterBy=Name

ユーザーがフィルターを適用した後に並べ替えリンクを押したときに欲しい-フィルターは失われないので、パラメーターを組み合わせる方法が必要です。私の推測では、クエリ文字列を解析せずに、MVCオブジェクトからパラメータのコレクションを取得する方法があるはずです。

39
Alexander Taran

これまでのところ、私が考え出した最良の方法は、_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)%>
_
29
Alexander Taran

私のソリューションはqwerty1000に似ています。標準のActionQueryLinkと同じ基本パラメーターを受け取る拡張メソッドActionLinkを作成しました。 Request.QueryStringをループし、RouteValues辞書に存在しないパラメーターを追加します(必要に応じて、元のクエリ文字列を上書きできます)。

既存の文字列を保持し、キーを追加しない場合の使用法は次のとおりです。

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

既存の文字列を保持して新しいキーを追加するには、次のようにします。

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

以下のコードは2つの使用法を示していますが、必要に応じて他の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);
    }
12
Brian Cauthon
<%= 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アカウントに。

8
Mehrdad Afshari

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
user170868

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

クエリ文字列は次のようになります。

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

class="cssClass"

2