If you feel you would like further background, I have previously posted and accepted this. Correctly making an ActionLink extension with htmlAttributes
This is a followup question. My problem is that I have two custom extentions where one calls the other. For some reason the htmlAttributes are rendering out like this.
<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]"
...</a>
The above occurs when I call ActionImageLink2. The purpose of ActionImageLink2 is only to add attributes pairs. How can I make it that Keys and Values render correctly?
There is something up with the HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)
public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string imageUrl, string altText, RouteValueDictionary routeValues, string _imageClass = "", object htmlAttributes = null)
{
var image = new TagBuilder("img");
image.MergeAttribute("src", imageUrl);
image.MergeAttribute("alt", altText);
if (string.IsNullOrEmpty(_imageClass) == false) image.MergeAttribute("class", _imageClass);
var link = helper.ActionLink("[replaceme]", routeValues, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
return new MvcHtmlString(link.ToHtmlString().Replace("[replaceme]", image.ToString(TagRenderMode.SelfClosing)));
}
public static MvcHtmlString ActionImageLink2(this HtmlHelper helper, string imageUrl, string altText, RouteValueDictionary routeValues, string updateTarget, string _imageClass = "", object htmlAttributes = null)
{
RouteValueDictionary htmlAttr = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
htmlAttr.Add("data-ajaxget-click", "");
htmlAttr.Add("data-ajax-update", (updateTarget.Contains("#") ? updateTarget : "#" + updateTarget));
return helper.ActionImageLink(imageUrl, altText, routeValues, _imageClass, htmlAttr);
}
public static MvcHtmlString ActionLink(this HtmlHelper helper, string linkText, RouteValueDictionary routeValues, object htmlAttributes = null)
{
return helper.ActionLink(linkText, routeValues["Action"].ToString(), routeValues["Controller"].ToString(), routeValues, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
}
Each ActionLink has a second line which is printing as ToHtmlString. The printscreen below shows the result.
@{RouteValueDictionary route = new RouteValueDictionary();
route["Area"] = "";
route["Controller"] = "Test";
route["Action"] = "Test";
}
@Html.ActionLink("Html.ActionLink", route, new { style = "color: green" })
<br />
@Html.ActionLink("Html.ActionLink", route, new { style = "color: green" }).ToHtmlString()
<br />
<br />
@Html.ActionImageLink("https://stackoverflow.com/users/flair/511438.png", "alt text", route, "image class", new { style = "background-color: orange" })
<br />
@Html.ActionImageLink("https://stackoverflow.com/users/flair/511438.png", "alt text", route, "image class", new { style = "background-color: orange" }).ToHtmlString()
<br />
<br />
@Html.ActionImageLink2("https://stackoverflow.com/users/flair/511438.png", "alt text", route, "partialDiv", "image class", new { style = "background-color: orange" })
<br />
@Html.ActionImageLink2("https://stackoverflow.com/users/flair/511438.png", "alt text", route, "partialDiv", "image class", new { style = "background-color: orange" }).ToHtmlString()
I'd do something like this:
public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string imageUrl, string altText, RouteValueDictionary routeValues, string _imageClass = "", IDictionary<String, object> htmlAttributes = null)
{
//...functionality omitted...
var link = helper.ActionLink("[replaceme]", routeValues, htmlAttributes);
//... other ....
}
public static MvcHtmlString ActionImageLink(this HtmlHelper helper, string imageUrl, string altText, RouteValueDictionary routeValues, string _imageClass = "", object htmlAttributes = null)
{
return helper.ActionImageLink(imageUrl, altText, routeValues, _imageClass, new RouteValueDictionary(htmlAttributes));
}
public static MvcHtmlString ActionLink(this HtmlHelper helper, string linkText, RouteValueDictionary routeValues, object htmlAttributes = null)
{
return helper.ActionLink(linkText, routeValues, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString ActionLink(this HtmlHelper helper, string linkText, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes = null)
{
return helper.ActionLink(linkText, routeValues["Action"].ToString(), routeValues["Controller"].ToString(), routeValues, htmlAttributes);
}
In a nutshell: overloading
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With