views:

185

answers:

3

I'm trying to add a navigational menu for my project which uses the ASP.NET framework and C# programming language. My solution is to create a widget which can populate a partial view when called from the master page. In the widget's action method, how do I add Links or Controller-Action combinations to the ViewDataDictionary?

--- Edit : Here is my code, after your suggestion

public class NavController : Controller
{
    public ActionResult Menu()
    {     
  List<ActionLink> navLinks = new List<ActionLink>();
  navLinks.Add(new ActionLink() { Text = "Home", ActionName = "Index", ControllerName = "Home" });
  return View(navLinks);   
 }
}

The partial view file looks like the following:

<%@ Control Language="C#"  Inherits="System.Web.Mvc.ViewUserControl<List<Microsoft.Web.Mvc.Controls.ActionLink>>" %>

<% foreach(var link in Model) { %>
<%= link %>
<%}  %>

But the output of all this is simply 'Microsoft.Web.Mvc.Controls.ActionLink' and not the link which I want.

Thanks.

A: 

Is it what you're looking for?

  List<ActionLink> actions = new List<ActionLink>(); //or = ViewData["actions"] for adding
  actions.Add(new ActionLink() { ActionName = "actionname", ControllerName = "controller" });
  ViewData["actions"] = actions;
twk
Hi, thanks for your response. I tried your method but I'm sure I'm still doing something wrong here. Please see above.
Dhruv
Use link's RenderControl method or ToString - I can't test now. Lets check out yourself which one renders the link.
twk
Thanks for you time, which is unfortunately scarce at my end as well. I'll explore this later after the demo tomorrow when I refactor other sections of code.
Dhruv
A: 

Ok, I figured out a straightforward approach by adding ViewData directly to the dictionary.

public ActionResult Menu()
{
 ViewData.Add("one", "<a href=\"../Home/Index\">Home</a>");
 ViewData.Add("two", "<a href=\"../Account/LogOff\">Log Off</a>");

 return View();
}

In the partial view:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<ul>
<% foreach (KeyValuePair<string, object> pair in ViewData) { %>

<li>
 <%=pair.Value %>
</li>

<%}  %>
</ul>

May not be the most clever way to do this, but it works.

Dhruv
+2  A: 

The actionlink is a mvc control of some sort that would be the result of parsing a tag and would then be added to the controls collection of the page.

You have 2 options to achieve your goal, pass in the complete links ( i.e. the fully formed anchor tag ) which you could generate in your controller using Html.ActionLink( linkText, actionName) or pass the details of the link to your partial and use those details to generate the links ( i.e. pass an enumeration of elements containing the details of your links ).

Personally I prefer the second approach as it separates the navigation logic from the rendering.

Somewhere in your code ...

public class NavigationLink
{
  public string Text;
  public string Controller;
  public string Action;
  // ... any other properties you want to pass
}

Somewhere in your controller ...

public ActionResult Menu
{
  var links = new List<NavigationLink>
  {
    new NavigationLink
    {
      Text = "Home",
      Controller = "Home",
      Action = "Index"
    },
    new NavigationLink
    {
      Text = "Logout",
      Controller = "Authentication",
      Action = "Logout"
    }
  };

  return View( links );
}

Somewhere in your view ...

<%@ Control Language="C#"  Inherits="System.Web.Mvc.ViewUserControl<List<NavigationLink>>" %>

<% foreach(var link in Model) { %>
<%= Html.ActionLink( link.Text, link.Action, link.Controller ) %>
<%}  %>
Neal