8

検索結果を表示するページがあるとします。stackoverflow を検索すると、1 ページあたり 10 件、5000 件の結果が返されます。そのページにリンクを作成するときに、次のようにしていることに気付きました。

<%=Html.ActionLink("Page 1", "Search", new { query=ViewData["query"], page etc..%>
<%=Html.ActionLink("Page 2", "Search", new { query=ViewData["query"], page etc..%>
<%=Html.ActionLink("Page 3", "Search", new { query=ViewData["query"], page etc..%>
<%=Html.ActionLink("Next", "Search", new { query=ViewData["query"], page etc..%>

私はこれが好きではありません.以前に投稿されたものなどを注意深く考慮してリンクを作成する必要があります..

私がやりたいことは

<%=Html.BuildActionLinkUsingCurrentActionPostData
        ("Next", "Search", new { Page = 1});

匿名辞書は、以前のアクションによって現在設定されているものを上書きします。

基本的に、私は以前のアクション パラメータが何であったかを気にします。再利用したいからです。単純に聞こえますが、並べ替えや高度な検索オプションのロードを追加し始めると、面倒になり始めます。

私はおそらく明らかな何かを見逃しています

4

8 に答える 8

11

HtmlHelper 内で同様の問題が発生しました。パラメータを少し調整して(ページ番号を増やすことを考えてください)、現在のページに戻るリンクを生成したかったのです。したがって、URL が /Item/?sort=Name&page=0 の場合、同じページへのリンクを作成できるようにしたいと考えていましたが、ページ パラメータを変更するだけで、並べ替えパラメータが自動的に含まれるようになりました (つまり、/Item/?sort=名前&ページ=1)。

私の解決策はこれでした(HtmlHelper拡張メソッドで使用しますが、MVCのほぼどこでも同じデータにアクセスできるため、用途に合わせて簡単に調整できます):

private static RouteValueDictionary CreateRouteToCurrentPage(HtmlHelper html)
{
    RouteValueDictionary routeValues 
         = new RouteValueDictionary(html.ViewContext.RouteData.Values);

    NameValueCollection queryString 
         = html.ViewContext.HttpContext.Request.QueryString;

    foreach (string key in queryString.Cast<string>())
    {
        routeValues[key] = queryString[key];
    }

    return routeValues;
}

メソッドが行うことは、現在のリクエストの RouteValueDictionary を取得し、そのコピーを作成することです。次に、クエリ文字列で見つかった各クエリ パラメーターをこのルートに追加します。これは、何らかの理由で、現在のリクエストの RouteValueDictionary にそれらが含まれていないためです (含まれていると思いますが、含まれていません)。

次に、結果の辞書を取得して、その一部のみを変更できます。次に例を示します。

routeValues["page"] = 2;

次に、その辞書をすぐに使用できる HtmlHelper メソッドに渡して、URL などを生成できるようにします。

于 2009-08-04T15:12:02.623 に答える
1

次のヘルパー メソッドはまさにそれを行います。

    public static string EnhancedActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, bool keepQueryStrings)
    {
        ViewContext context = helper.ViewContext;
        IDictionary<string, object> htmlAttributes = null;
        RouteValueDictionary routeValues = null;
        string actionLink = string.Empty;
        if (keepQueryStrings && context.RequestContext.HttpContext.Request.QueryString.Keys.Count > 0)
        {
            routeValues = new RouteValueDictionary(context.RouteData.Values);
            foreach (string key in context.RequestContext.HttpContext.Request.QueryString.Keys)
            {
                routeValues[key] = context.RequestContext.HttpContext.Request.QueryString[key];
            }
        }            
        actionLink = helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
        return actionLink;
    }
于 2009-10-17T11:59:11.987 に答える
1

あなたがここで実際に何をしようとしているのか、私は少し不安です。リンクのリストを作成するプロセスを、リンク間の小さな変更のみで自動化しようとしていると思います。どうやらあなたの場合、「ページ」のID番号です。

おそらく最善ではないかもしれませんが、それを行う1つの方法は次のとおりです(私のコードは基本的で不自然な製品リストを使用し、ViewPageとPartialViewPageは両方とも厳密に型指定されたモデルを使用します):

ViewPage に、次のようなコードを追加します。

<div id="product_list">
        <% foreach (TestMVC.Product product in ViewData.Model)
           { %>
            <% Html.RenderPartial("ProductEntry", product); %>
        <% } %>
</div>

私の場合は「ProductEntry」の部分ビューは、次のようになります。

<div class="product">
    <div class="product-name">
        <%= Html.ActionLink(ViewData.Model.ProductName, "Detail", new { id = ViewData.Model.id })%>
    </div> 
    <div class="product-desc">
        <%= ViewData.Model.ProductDescription %>
    </div>       
</div>

その部分ビューで行っているのは、Html.RenderPartial の呼び出しによって親ビューから渡されたモデル/ビューデータを消費することだけです。

親ビューでは、関心のある特定の値を設定するために、Html.RenderPartial を呼び出す前にモデル オブジェクトのパラメーターを変更できます。

お役に立てれば。

于 2008-09-23T19:57:57.250 に答える
1

ビューで冗長なコードを書いていることに気付いたときはいつでも、 helperを書いてください。ヘルパーは、現在行っているようにパラメーターを明示的にコピーすることも、コレクション全体を反復処理して自動的にコピーすることもできます。私だったら前者を選ぶと思います。次に、リンクを作成するたびにパラメーターを再構築する代わりに、新しいヘルパーを呼び出すだけです。

于 2008-09-23T17:25:56.927 に答える
0

さまざまなソリューションを試して何時間も費やした後、これだけがうまくいきました: MVC ActionLinkは、現在のURLからすべての(オプションの)パラメーターを追加します

于 2011-06-14T05:23:31.687 に答える
0

これがactionlink拡張機能です


  public static class ActionLinkExtension
    {
        public static MvcHtmlString ActionLinkWithQueryString(this HtmlHelper helper, string linkText, string action, string controller, object routeValues)
        {
            var context = helper.ViewContext;

            var currentRouteValues = new RouteValueDictionary(context.RouteData.Values);
            foreach (string key in context.HttpContext.Request.QueryString.Keys)
            {
                currentRouteValues[key] = context.HttpContext.Request.QueryString[key];
            }

            var newRouteValues = new RouteValueDictionary(routeValues);

            foreach (var route in newRouteValues)
            {
                if (!currentRouteValues.ContainsKey(route.Key))
                {
                    currentRouteValues.Add(route.Key, route.Value);
                }
                else
                {
                    currentRouteValues[route.Key] = route.Value;
                }
            }

            return helper.ActionLink(linkText, action, controller, currentRouteValues, null);
        }

    }

于 2012-07-03T06:51:08.943 に答える
0

これを見てください。良い例です: http://nerddinnerbook.s3.amazonaws.com/Part8.htm

于 2010-12-03T13:22:46.677 に答える
0

正確な答えではありませんが、指摘する価値があります。ページング機能が必要な場合は、PagedList Nuget パッケージを使用してください (車輪を再発明する必要はありません)。次のリンクは、それを使用する方法の本当に良い例を提供します: ASP.NET チュートリアル

ページを切り替えるときにクエリ文字列が URL に保存されるため、これは特に便利です。

于 2012-07-16T13:20:54.420 に答える