so here it goes:
I have a html helper which renders ActionLink
s with the optional parameters of the current url in it. this html helper also lets you add some more optional parameters as you please and merges them in 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 perfect, but I now 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 this does NOT work. it compiles, but my URL looks not 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&Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&Values=System.Collections.Generic.Dictionary%602%2BValueCollection%5BSystem.String%2CSystem.Object%5D">Back to List</a>
as you see, what previously did work, now doesnt because it takes the RouteValueDictionary
s as objects, which gives me not the result I want.
so I thought, What if i make them RouteValueDictionary
s again.
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 too gives me the url i just posted above.
Why did this work in my ActionLinkwParams
method, but not when the ActionLinkwParams
calls the SecurityTrimmedActionLink
method? and how do I fix this?
Modify the signature of the SecurityTrimmedActionLink
method to this:
public static string SecurityTrimmedActionLink(
this HtmlHelper htmlHelper,
string linkText,
string action,
string controller,
RouteValueDictionary extraRVs,
RouteValueDictionary htmlAttributes
)
Notice the difference between this and this. In your case (the one that doesn't work) you are calling the second overload taking objects but in your case you are not passing anonymous objects but a RouteValueDictionary which is treated as if it was an anonymous object and its public properties (Count, Keys, Values) are serialized as attributes.
Remark: Your helper methods are not correct. They return strings. This is not how it is supposed to be. Helper methods should return MvcHtmlString.
So instead of
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);
}