【问题标题】:RouteValueDictionary/object problem in mvc ActionLinkmvc ActionLink 中的 RouteValueDictionary/object 问题
【发布时间】:2011-01-05 11:34:20
【问题描述】:

就这样吧:

我有一个 html 助手,它使用其中当前 url 的可选参数呈现 ActionLinks。这个 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>

如您所见,以前有效,现在无效,因为它将RouteValueDictionarys 作为对象,这没有给我想要的结果。

所以我想,如果我再次将它们设为RouteValueDictionarys 会怎样。

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

但这也给了我刚刚在上面发布的网址。 为什么这在我的ActionLinkwParams 方法中起作用,但在ActionLinkwParams 调用SecurityTrimmedActionLink 方法时不起作用?我该如何解决这个问题?

【问题讨论】:

    标签: asp.net-mvc actionlink routevalues


    【解决方案1】:

    SecurityTrimmedActionLink方法的签名修改为:

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

    注意thisthis 之间的区别。在您的情况下(不起作用的那个),您正在调用第二个重载对象,但在您的情况下,您不是传递匿名对象而是传递一个 RouteValueDictionary ,它被视为一个匿名对象及其公共属性(计数, Keys, Values) 被序列化为属性。

    备注:您的辅助方法不正确。他们返回字符串。这不是应该的样子。辅助方法应返回 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);
    }
    

    【讨论】:

    • 我不能这样做,因为有时我会直接调用 SecurityTrimmedActionLink,在这种情况下我会以 new{id=something} 的形式发送对象
    • @Stefanvds,如果你想要正确的属性,你必须这样做,否则你需要将一个私有方法和另一个公开。
    • 我知道这是因为 Actionlink 的重载方法,但为什么这在我的第一个版本中有效?我看不出有什么不同。我的方法中也有对象....
    • @Stefanvd,在您的第一个示例中,您将其称为:msdn.microsoft.com/en-us/library/dd504988.aspx。你看到它需要 RouteValueDictionary 吗?在您的第二个示例中,您正在调用带有对象的对象,因此您需要传递一个匿名对象,例如 new { foo = "bar" },它应该输出 foo="bar" 属性,但您传递的是一个输出 Keys="3" Values="..." 的 RouteValueDictionary。
    • 当我将两个“对象”解析为“routevaluedictionary”时,为什么它不调用此方法msdn.microsoft.com/en-us/library/dd504988.aspx
    【解决方案2】:

    所以我最终所做的(感谢 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;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      相关资源
      最近更新 更多