5

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?

tereško
  • 58,060
  • 25
  • 98
  • 150
Thijs
  • 3,015
  • 4
  • 29
  • 54

2 Answers2

3

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));
    }
}
Thijs
  • 3,015
  • 4
  • 29
  • 54
  • 1
    nit: instead of calling `HtmlHelper.AnonymousObjectToHtmlAttributes(routeValues)`, use `new RouteValueDictionary(routeValues)` constructor. The helper method is essentially a wrapper of that and only exists to avoid confusion over the naming. – bhamlin Dec 13 '13 at 21:39
  • Thanks fot the tip. I've changed it in the awnser. – Thijs Dec 13 '13 at 22:08
1

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.

Dmitry Efimenko
  • 10,973
  • 7
  • 62
  • 79
  • Thank you for the link, I didn't knew of that! Still I would like to implement it myself because at the moment a license is required for BS3. – Thijs Nov 19 '13 at 23:11
  • That's perfectly fine. Feel free to review/use the code from github (linked above). – Dmitry Efimenko Nov 19 '13 at 23:24
  • it's string, string, string, object, Dictionary that I'm using. I'm going for this overload: http://msdn.microsoft.com/en-us/library/dd504972(v=vs.108).aspx – Thijs Nov 20 '13 at 07:29
  • Well, there is no overload `string, string, string, object, Dictionary` either. Your link shows that and intellisens in VS shows that. Just see what overloads there are and go from there. – Dmitry Efimenko Nov 20 '13 at 17:36