Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HtmlAttributes in Extension Method

I'm using MVC 5 and I'm trying to write some Bootstrap extention methods. My goal is to 'overwrite' the Html.ActionLink method with Html.BootstrapLinkButton. The BootstrapLinkButton method should generate a link with the css classes "btn btn-default"automatically attached. My code so far:

public static MvcHtmlString BootstrapLinkButton(this HtmlHelper htmlHelper, 
    string linkText,string actionName, string controllerName, 
    object routeValues = null, object htmlAttributes = null)
    {
        var attributes = 
            HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

        if (attributes.ContainsKey("class"))
        {
            object value;
            attributes.TryGetValue("class", out value);
            value = (value as string) + " btn btn-default";
            attributes["class"] = value;
        }
        else
        {
            attributes["class"] = "btn btn-default";
        }

        return htmlHelper.ActionLink(
            linkText, actionName, controllerName, routeValues, 
            new Dictionary<string, object>(attributes));
    }

which gives me the following result in the HTML:

<a comparer="System.Collections.Generic.GenericEqualityComparer`1[System.String]"
   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="/test/test/">
     Test
</a>

I searched the internet, but nothing seems to fix this problem. Does anyone knows the magic code to fix this?

like image 887
Thijs Avatar asked Oct 03 '22 09:10

Thijs


2 Answers

If my solution could help anyone, here it is:

    public static MvcHtmlString BootstrapLinkButton(this HtmlHelper htmlHelper, 
        string linkText, 
        string actionName, 
        string controllerName = null, 
        object routeValues = null, 
        object htmlAttributes = null,
        string btnStyle = "default")
    {
        var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        controllerName = 
            controllerName ?? 
            HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();

        if (attributes.ContainsKey("class"))
        {
            object value;
            attributes.TryGetValue("class", out value);
            value = string.Format("{0} btn btn-{1}", (value as string), btnStyle);
            attributes["class"] = value;
        }
        else
        {
            attributes["class"] = string.Format("btn btn-{0}", btnStyle);
        }

        return htmlHelper.ActionLink(
            linkText, 
            actionName, 
            controllerName, 
            new RouteValueDictionary(routeValues), 
            new Dictionary<string, object>(attributes));
    }
}
like image 146
Thijs Avatar answered Oct 13 '22 10:10

Thijs


It's already implemented in TwitterBootstrapMVC

Here is some relevant code

Most likely the reason your code is failing is because htmlHelper.ActionLink(...) method there is confused about which overload needs to be used. There is no overload on it that takes string, string, object, Dictionary, which is what you are trying to pass to it.

like image 22
Dmitry Efimenko Avatar answered Oct 13 '22 10:10

Dmitry Efimenko