Michiel
Michiel

Reputation: 4260

Generate actionlinks with model data

I would like to fill a list of actionlinks with data from a model. In order to achieve this I created a model called ActionLinkModel

public class ActionLinkModel
{
    public ActionLinkModel(string linkText, string actionName = "Index", string controllerName = "Home", Dictionary<string, string> routeValues = null, Dictionary<string, string> htmlAttributes = null)
    {
        LinkText = linkText;
        ActionName = actionName;
        ControllerName = controllerName;
        RouteValues = routeValues == null ? new Dictionary<string, string>() : routeValues;
        HtmlAttributes = htmlAttributes == null ? new Dictionary<string, string>(): htmlAttributes;
        if(!HtmlAttributes.ContainsKey("title")) {
            HtmlAttributes.Add("title",linkText);
        }
    }

    public string LinkText { get; set; }
    public string ActionName { get; set; }
    public string ControllerName { get; set; }
    public Dictionary<string, string> RouteValues { get; set; }
    public Dictionary<string, string> HtmlAttributes { get; set; }

}

Then in my view I call it like this:

@foreach (var link in Model.Links) {
   @Html.ActionLink(link.LinkText, link.ActionName, link.ControllerName, link.RouteValues, link.HtmlAttributes);
} 

Unfortunately this doesn't render the way i was hoping for, the problem is with routevalues and htmlAttibutes. I can't figure out what type they need to be, in the signature of Html.Actionlink I see they are either objects or RouteValueDictionary / IDictionary. Also I have seen constructions like this:

Html.ActionLink("Home", "Index", "Home", null, new { title="Home", class="myClass"})

but what type is new { title="Home", class="myClass"} creating?

How do i do this?, i would like to take care of things in the model and keep the code in the view as simple as possible.

Upvotes: 0

Views: 121

Answers (1)

Kami
Kami

Reputation: 19407

new { title="Home", class="myClass"} 

gets translated to an anonymous object, with the supplied property values.

To answer your question, you will need to modify the Model object to the following. The Dicationary objects need to be Dictionary<string,object>.

public class ActionLinkModel
{
    public string LinkText { get; set; }
    public string ActionName { get; set; }
    public string ControllerName { get; set; }
    public IDictionary<string, object> RouteValues { get; set; }
    public IDictionary<string, object> HtmlAttributes { get; set; }
}

And in the view code use the following

@foreach (var link in Model.Links) {
    @Html.ActionLink(link.LinkText, link.ActionName, link.ControllerName, new RouteValueDictionary(model.RouteValues), model.HtmlAttributes)
} 

We are wrapping the dictionary object to a RouteValueDictionary. If you do not, then it will get translated to the Object overload by the CLR and will give incorrect results.

Upvotes: 1

Related Questions