Tell don't ask

July 26, 2010

ASP.NET and JQuery MVC Menu Part 3 (AJAX)

Filed under: Uncategorized — telldontask @ 9:09 am
Other posts in this series:

Aaron has very kindly sent me an extension to the original code for creating a simple menu for ASP.NET MVC sites. His version employs the Microsoft AJAX library to “ajaxify” the links on the menu.

The main part of his code handles getting a List Item containing an AJAX link.

  1. public static class Extention
  2.     {
  3.         public static TagBuilder GetNavItem(this AjaxHelper ajax, MolineSoftware.SLAudit.Navigation navItem)
  4.         {
  5.             MvcHtmlString htmlTemplate = null;
  6.             if (navItem.Route == null)
  7.             {
  8.                 htmlTemplate =
  9.                     ajax.ActionLink(navItem.LinkText, navItem.ActionName, navItem.Controller,
  10.                                     new AjaxOptions
  11.                                         {
  12.                                             UpdateTargetId = navItem.UpdateTargetId,
  13.                                             OnSuccess = navItem.OnSuccess,
  14.                                             OnBegin = navItem.OnBegin
  15.                                         });
  16.             }
  17.             else
  18.             {
  19.                 htmlTemplate =
  20.                     ajax.ActionLink(navItem.LinkText, navItem.ActionName, navItem.Controller, navItem.Route,
  21.                                     new AjaxOptions
  22.                                         {
  23.                                             UpdateTargetId = navItem.UpdateTargetId,
  24.                                             OnSuccess = navItem.OnSuccess,
  25.                                             OnBegin = navItem.OnBegin
  26.                                         });
  27.             }
  28.             var builder = new TagBuilder("li");
  29.             if (IsCurrentAction(ajax, navItem.ActionName, navItem.Controller))
  30.                 builder.MergeAttribute("class", "current");
  31.             builder.InnerHtml = htmlTemplate.ToHtmlString();
  32.             return builder;
  33.         }
  34.         static bool IsCurrentAction(AjaxHelper ajax, string actionName, string controllerName)
  35.         {
  36.             string currentControllerName = (string) ajax.ViewContext.RouteData.Values["controller"];
  37.             string currentActionName = (string) ajax.ViewContext.RouteData.Values["action"];
  38.             if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) &&
  39.                 currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase))
  40.             {
  41.                 return true;
  42.             }
  43.             return false;
  44.         }
  45.     }
  46. }

You will notice the use of a class called Navigation (to build the actual link).

  1. public class Navigation
  2. {
  3.     #region | Public Properties |
  4.  
  5.     /// <summary>
  6.     /// Gets or Sets the ID
  7.     /// </summary>
  8.     public virtual Int32 Id { get; set; }
  9.  
  10.     /// <summary>
  11.     /// Gets or Sets the Display for the link
  12.     /// </summary>
  13.     public virtual String LinkText { get; set; }
  14.  
  15.     /// <summary>
  16.     /// Gets or Sets the ActionName.
  17.     /// </summary>
  18.     public virtual String ActionName { get; set; }
  19.  
  20.     /// <summary>
  21.     /// Gets or Sets the Controller
  22.     /// </summary>
  23.     public virtual String Controller { get; set; }
  24.  
  25.     /// <summary>
  26.     /// Gets or sets the Active flag.
  27.     /// </summary>
  28.     public virtual Boolean Active { get; set; }
  29.  
  30.     /// <summary>
  31.     /// Gets or sets the JavaScript function to call after the page is successfully updated.
  32.     /// </summary>
  33.     public virtual String OnSuccess { get; set; }
  34.  
  35.     /// <summary>
  36.     /// Gets or sets the name of the JavaScript function to call immediately before the page is updated.
  37.     /// </summary>
  38.     public virtual String OnBegin { get; set; }
  39.  
  40.     /// <summary>
  41.     /// Gets or sets the ID of the DOM element to update by using the response from the server.
  42.     /// </summary>
  43.     public virtual String UpdateTargetId { get; set; }
  44.  
  45.     /// <summary>
  46.     /// Gets or Sets the <see cref="RouteValueDictionary"/>
  47.     /// </summary>
  48.     public virtual object Route { get; set; }
  49.  
  50.     #endregion
  51. }

We can then create a collection of these navigation items…

  1. namespace MolineSoftware.SLAudit
  2. {
  3.     public class NavigationList : List<Navigation>
  4.     {
  5.         #region | Constructor |
  6.  
  7.         #endregion
  8.  
  9.         ///Returns a NavigationList of items ** TESTING ONLY
  10.         public NavigationList GetTestList()
  11.         {
  12.             NavigationList list = new NavigationList();
  13.  
  14.             list.Add(new Navigation
  15.                          {
  16.                              Active = true,
  17.                              Controller = "Home",
  18.                              OnBegin = "SetLoading",
  19.                              OnSuccess = "handleUpdate",
  20.                              Id = 1,
  21.                              LinkText = "Home",
  22.                              ActionName = "Index",
  23.                              UpdateTargetId = "output-data",
  24.                              Route = new {serverName = "MyServer"} //Example setting the route object
  25.                          });
  26.  
  27.  
  28.             list.Add(new Navigation
  29.                          {
  30.                              Active = true,
  31.                              Controller = "Home",
  32.                              OnBegin = "SetLoading",
  33.                              OnSuccess = "handleUpdate",
  34.                              Id = 2,
  35.                              LinkText = "About",
  36.                              ActionName = "About",
  37.                              UpdateTargetId = "output-data"
  38.                          });
  39.             return list;
  40.         }
  41.     }

Finally we can use this code (assuming model is an instance of our NavigationList class) to render the menu.

  1. <% foreach (var menu in Model as MolineSoftware.SLAudit.NavigationList) { %>
  2.     <%= Ajax.GetNavItem(menu)%>
  3. <% } %>

July 13, 2010

Upgrading to ASP.NET MVC 2/.net 4

Filed under: Uncategorized — telldontask @ 8:26 am

We have recently upgraded a few projects to .net 4 (and MVC 2) and have invariably hit one particular error message.

We are using the Spark view engine, and having upgraded the project to MVC 2 would see this error…

Dynamic view compilation failed. (0,0): warning CS1701: Assuming assembly reference ‘System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′ matches ‘System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35′, you may need to supply runtime policy

Google helped us find this post, which explains that any referenced assemblies which in turn reference MVC 1 could be causing this issue.

After a prolonged process of checking and upgrading various assemblies, we eventually discovered that we needed to update our _Global.spark file.

This file (for those who haven’t used it) is a useful place to put anything which all the spark pages in your project need to include.

Ours looked like this…

<use namespace="Microsoft.Web.Mvc" />
<use namespace="MvcContrib" />
<use namespace="MvcContrib.UI" />
<use namespace="MvcContrib.UI.Pager" />
<use namespace="MvcContrib.FluentHtml" />
<use namespace="System" />
<use namespace="System.Data" />
<use namespace="System.Collections.Generic" />
<use namespace="System.Web.Mvc" />
<use namespace="System.Web.Mvc.Html" />
<use namespace="Autoclimate.Framework.Extensions" />
<use namespace="Catalogue.Web.Code" />
<use namespace="xVal.Html" />

We’d upgraded most of these to the latest versions, except for xVal. Removing xVal from this list fixed the problem. As it happens we were no longer using xVal (in the spark pages) so we didn’t need it in there anyway.

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.