4

だからここに行く:

ActionLink現在の URL のオプションのパラメーターを使用して sをレンダリングする html ヘルパーがあります。この html ヘルパーを使用すると、必要に応じてオプションのパラメーターをさらに追加して、それらを 1 にマージすることもできますRouteValueDictionary

    public static string ActionLinkwParams(this HtmlHelper helper, string linktext, string action, string controller, object extraRVs, object htmlAttributes) {

        //get current optional params from current URL
        NameValueCollection c = helper.ViewContext.RequestContext.HttpContext.Request.QueryString;

        //put those in a dict
        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);

        //merge them
        RouteValueDictionary m = RouteValues.MergeRouteValues(r, extra);

        return helper.ActionLink(linktext, action, controller, m, htmlAtts).ToHtmlString();
    }

これは完璧に機能しますが、SecurityAware Actionlinks を追加しました。

それで

        return helper.ActionLink(linktext, action, controller, m, htmlAtts).ToHtmlString();

になる

        return helper.SecurityTrimmedActionLink(linktext, action, controller, m, htmlAtts);

次に呼び出します:

   public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, object extraRVs, object htmlAttributes) {
        return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, extraRVs, htmlAttributes, false);
    }

    public static string SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, object extraRVs, object htmlAttributes, bool showDisabled) {
        if (controller == null) {
            RouteData routeData = htmlHelper.ViewContext.RouteData;
            controller = routeData.GetRequiredString("controller");
        }
        if (IsAccessibleToUser(action, controller)) {
            return htmlHelper.ActionLink(linkText, action, controller, extraRVs, htmlAttributes).ToHtmlString();
        } else {
            return showDisabled ? String.Format("<span>{0}</span>", linkText) : "";
        }
    }

これは機能しません。コンパイルはできますが、私の URL は見栄えがよくありません。

   <a count="3" keys="System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]" values="System.Collections.Generic.Dictionary`2+ValueCollection[System.String,System.Object]" href="/2011-2012/Instelling?Count=3&amp;Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&amp;Values=System.Collections.Generic.Dictionary%602%2BValueCollection%5BSystem.String%2CSystem.Object%5D">Back to List</a>

ご覧のとおり、以前は機能していたものが s をオブジェクトとして使用するため、現在は機能しRouteValueDictionaryていません。これにより、必要な結果が得られません。

だから私は思った、RouteValueDictionaryもう一度 s にしたらどうだろう。

       if (IsAccessibleToUser(action, controller)) {

            RouteValueDictionary parsedextraRVs = null;
            if (extraRVs != null && extraRVs.GetType().Name == "RouteValueDictionary") {
                parsedextraRVs = (RouteValueDictionary)extraRVs;
            }

            RouteValueDictionary parsedHtmlAttributes = null;
            if (htmlAttributes != null && htmlAttributes.GetType().Name == "RouteValueDictionary") {
                parsedHtmlAttributes = (RouteValueDictionary)htmlAttributes;
            }


            return htmlHelper.ActionLink(linkText, action, controller, parsedextraRVs == null ? extraRVs : parsedextraRVs, parsedHtmlAttributes == null ? htmlAttributes : parsedHtmlAttributes).ToHtmlString();
        }

しかし、これも私が上に投稿したURLを教えてくれます。なぜこれが私のActionLinkwParamsメソッドで機能したのに、メソッドをActionLinkwParams呼び出すときに機能しなかったのSecurityTrimmedActionLinkですか? どうすればこれを修正できますか?

4

2 に答える 2

7

SecurityTrimmedActionLinkメソッドのシグネチャを次のように変更します。

public static string SecurityTrimmedActionLink(
    this HtmlHelper htmlHelper, 
    string linkText, 
    string action, 
    string controller, 
    RouteValueDictionary extraRVs, 
    RouteValueDictionary htmlAttributes
)

thisthisの違いに注意してください。あなたの場合(機能しないもの)、オブジェクトを取得する2番目のオーバーロードを呼び出していますが、あなたの場合、匿名オブジェクトを渡していませんが、匿名オブジェクトであるかのように扱われるRouteValueDictionaryとそのパブリックプロパティ(Count、キー、値) は属性としてシリアル化されます。

注意: あなたのヘルパー メソッドは正しくありません。それらは文字列を返します。これは本来あるべき姿ではありません。ヘルパー メソッドはMvcHtmlStringを返す必要があります。

だから代わりに

public static string ActionLinkwParams(...)
{
    ...
    return helper.ActionLink(linktext, action, controller, m, htmlAtts).ToHtmlString();
}

そのはず:

public static MvcHtmlString ActionLinkwParams(...)
{
    ...
    return helper.ActionLink(linktext, action, controller, m, htmlAtts);
}
于 2011-01-05T11:53:46.780 に答える
0

それで、私が最後にしたこと (Darin に感謝) は、この作業を行うためにいくつかの余分なオーバーロードを作成しました。

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

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

    public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, object extraRVs) {
        return SecurityTrimmedActionLink(htmlHelper, linkText, action, null, extraRVs, null);
    }

    public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, object extraRVs) {
        return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, extraRVs, null);
    }

    public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, RouteValueDictionary extraRVs) {
        return SecurityTrimmedActionLink(htmlHelper, linkText, action, null, extraRVs, null);
    }

    public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, RouteValueDictionary extraRVs) {
        return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, extraRVs, null);
    }

    public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, object extraRVs, object htmlAttributes) {

        RouteValueDictionary rv = new RouteValueDictionary(extraRVs);
        RouteValueDictionary html = new RouteValueDictionary(htmlAttributes);

        return SecurityTrimmedActionLink(htmlHelper, linkText, action, controller, extraRVs, html);
    }

    public static MvcHtmlString SecurityTrimmedActionLink(this HtmlHelper htmlHelper, string linkText, string action, string controller, RouteValueDictionary extraRVs, IDictionary<String, Object> htmlAttributes) {
        if (controller == null) {
            RouteData routeData = htmlHelper.ViewContext.RouteData;
            controller = routeData.GetRequiredString("controller");
        }
        if (IsAccessibleToUser(action, controller)) {
            return htmlHelper.ActionLink(linkText, action, controller, extraRVs, htmlAttributes);
        } else {
            return MvcHtmlString.Empty;
        }
    }
于 2011-01-05T12:32:16.670 に答える