HtmlHelper-rendering Dictionary "keys" and "values" as attributes

If you feel that you want more information, I previously posted and accepted it. Correctly create an ActionLink extension with htmlAttributes

This is the next question. My problem is that I have two custom extensions where one calls the other. For some reason, htmlAttributes look 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 happens when I call ActionImageLink2. The purpose of ActionImageLink2 is only to add attribute pairs. How can I make the keys and values ​​display correctly?

There is something with HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)

Here are my extension methods

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

Here is my test view

Each ActionLink has a second line, which is printed as ToHtmlString. The printer screen 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() 

enter image description here

+6
source share
2 answers

I would 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 short: overload

+2
source

The problem I'm thinking of lies in this line:

 return helper.ActionImageLink(imageUrl, altText, routeValues, _imageClass, htmlAttr); 

of your ActionImageLink2 method. When you pass your htmlAttr variable to the ActionImageLink method, it is no more anonymous type.

So you get the problem when in ActionImageLink you call again

 HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes) 

Have you tried checking the type transfer before calling the specified function?

+1
source

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


All Articles