19

非常に有名なActionLink:

 <%: Html.ActionLink("Back to List", "Index")%>

これで、このリンクは [詳細] ビューに表示されました。インデックス ビューは検索ページです。その URL は次のようになります。

http://localhost:50152/2011-2012/Instelling/Details/76?gemeente=Dendermonde&postcode=92**&gebruikerscode=VVKSO114421&dossiernr=114421%20&organisatie=CLB

ご覧のとおり、かなりの数のパラメーターがあります。明らかに、インデックス ページに戻ったときにこれらすべてのパラメーターを保持したいので、ActionLink.

さて、私はそれを手動で行うのにうんざりしています。1 の場合は問題ありませんが、6 の場合は問題ありません。これははるかに簡単になるはずです。

ActionLink質問: 現在の URL のすべてのパラメーターをオプションとしてに返すにはどうすればよいですかRouteValues

を探していました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;
    }

詳細.aspx:

    <%: Html.ActionLink("Back to List", "Index", MVC2_NASTEST.MvcApplication.optionalParamters(Request.QueryString))%>

このコードをどこに配置するのが最適ですか? 私は推測しないGlobal.asax...

編集2:

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") %>
4

5 に答える 5

21

これが私が最終的に修正した方法であり、非常にうまく機能し、非常に DRY であるため、かなり誇りに思っています。

ビューでの呼び出し:

    <%: Html.ActionLinkwParams("Back to List", "Index")%>

ただし、オーバーロードを使用すると、通常の ActionLink が取るものなら何でもかまいません。

ヘルパー:

ヘルパーは、ルートにない URL からすべてのパラメーターを取得します。例: この URL:

http://localhost:50152/2011-2012/myController/Details/77?postalCode=9***&org=CLB

したがって、postalCode と Org を取得して、新しい 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;

        }
    }

}

オーバーロードを使用するビューで:

 <%: Html.ActionLinkwParams("Back to List", "Index","myController", new {testValue = "This is a test", postalCode=String.Empty}, new{ @class="test"})%>

URL には、いくつかの値を持つパラメーター postalCode があります。私のコードは、string.Empty に設定することにより、URL でそれらすべてを取得し、このパラメーターをリストから削除します。

最適化に関するコメントやアイデアを歓迎します。

于 2010-09-24T11:21:16.290 に答える
10

Request.QueryString のToRouteValueDictionary()拡張メソッドを作成して、 Html.ActionLinkをそのまま使用し、ビュー マークアップを簡素化します。

<%: Html.ActionLink("Back to List", "Index", Request.QueryString.ToRouteValueDictionary())%>

拡張メソッドは次のようになります。

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;
        }
    }
}

ビューで拡張メソッドを使用するには、次の質問と回答を参照してください: ASP.NET MVC ビューで拡張メソッドを使用するにはどうすればよいですか?

これはより単純で、受け入れられた回答よりもはるかに少ないコードで済みます。

于 2011-04-07T15:05:33.140 に答える
6

以下は、リクエストのルート値とクエリ文字列に基づいて RouteValueDictionary を作成する ViewContext の拡張メソッドです。

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;
        }
    }
}

作成した RouteValueDictionary を Html.ActionLink または Url.Action に渡すことができます

@Html.ActionLink("5", "Index", "Product",
    ViewContext.GetCombinedRouteValues(new { Page = 5 }),
    new Dictionary<string, object> { { "class", "page-link" } })

Page パラメーターが要求 URL に存在しない場合は、生成された URL に追加されます。存在する場合、その値は 5 に変更されます。

この記事には、私のソリューションのより詳細な説明があります。

于 2012-03-25T02:46:26.020 に答える
1
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 から取得できます

于 2010-09-24T16:13:50.367 に答える
0

おそらく最善の方法は、独自の 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
}
于 2010-09-23T15:34:48.543 に答える