Problem RouteValueDictionary / object in mvc ActionLink

so here it is:

I have an html helper that displays an ActionLink with optional parameters for the current url in it. this html helper also allows you to add additional parameters as you wish and combines them into 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(); } 

this works fine, but now I have added SecurityAware Actionlinks.

So

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

becomes

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

which then calls:

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

Now it does NOT work. it compiles, but my url doesn't look very good.

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

as you can see, what previously worked does not do it now, because it accepts RouteValueDictionary objects as objects, which does not give me the wrong result that I want.

so I thought, "What if I do them RouteValueDictionary .

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

but this also gives me the url that I just wrote above. Why does this work in my ActionLinkwParams method, but not when ActionLinkwParams calls the SecurityTrimmedActionLink method? and how to fix it?

+4
source share
2 answers

Change the signature of the SecurityTrimmedActionLink method as follows:

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

Pay attention to the difference between this and this . In your case (the one that does not work) you call the second overload object, but in your case you do not pass anonymous objects, and RouteValueDictionary, which is considered as an anonymous object and its public properties (Count, Keys, Values) are serialized as attributes.

Note. Your helper methods are incorrect. They return strings. It is not as it should be. Helper methods should return an MvcHtmlString .

So instead

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

it should be:

 public static MvcHtmlString ActionLinkwParams(...) { ... return helper.ActionLink(linktext, action, controller, m, htmlAtts); } 
+6
source

So, what I did at the end (thanks Darin), some extra overloads were done to make this work.

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

Source: https://habr.com/ru/post/1334350/


All Articles