MVC Related Posts by ThinqLinq

ThinqLinq Updated to MVC 4

As I work more in Visual Studio 2012, I found the need to make a small tweak to this web site, but discovered that the MVC 1 code base that the site was using is no longer a natively supported as part of Visual Studio 2012.  As a result, I took the plunge and re-wrote the UI portions of the site using MVC3 MVC 4 with the new Razor templating engine. This site is a test-bed of technologies I want to play with anyway. I also upgraded the site from .Net 3.5 to .Net 4. In light of these changes, please let me know if you see anything unexpected on the site.

I’m also in the process of revising the comment system from the home-grown version I was using, to a hosted comment system in the hopes to get more conversation going on the site. Feel free to comment using the new commenting system. If you have problems with the comments, please feel free to let me know on the Contact page. Thank you for your ongoing support.

Edit. Thanks to Amit Patel’s article, I was able to upgrade from MVC 3 to MVC 4 in less than 30 minutes (including deployment). I hope you appreciate the effort.

Posted on - Comment
Categories: MVC -

Site updated with MVC

In case you haven't been following along the recent posts, I've been exploring ASP.Net MVC recently using this site as a guinea pig. Today I deployed the updated bits and hope you find them to be an improvement on the older site. I've tried hard to keep backwards compatibility with the old site links via some tricks in the Routing engine. Please take a look around and let me know if you find any links that aren't quite working correctly. Please be patient as it may be a bit before all of the legacy kinks are worked out.

As with the previous versions of this site, I plan to make this code base available, but need to clean it up before releasing it.

Posted on - Comment
Categories: MVC - LINQ -

MVC Sitemap Navigation with XML Literals

As I continue re-writing this site to use MVC, I find more substructures that I can refactor easily. In the original implementation for the menu, I used the asp:Menu control. As I was working to theme the site, I had problems getting it to work acceptably with CSS styles. I also didn't like the reliance on tables.

In an effort to improve on it, I found the method of using unordered lists with list items for the menus (<ul> <li>). I then moved to a modified version of the UL SiteMap menu discussed by Byant Likes.

In moving to MVC, I was looking for a better option and found one on the MVC tutorial site. This builds the menu with a StringBuilder. I had a couple problems with this implementation however:

  • By using a StringBuilder, you don't get compiler assistance in validating the markup.
  • The implementation doesn't handle security trimming.
  • It only handles a single level of menu items.
  • For Each loops seem to be an anti-pattern for me with my LINQ experience.

To fix these issues, I figured we could re-write this relatively easily using XML Literals and VB with a recursive call to handle the potential n-levels of SiteMenuItems possible in the SiteMap XML specification. Even without adding any of the additional functionality, we can drastically simplify the implementation in the MVC Tutorial by re-writing it in XML Literals in VB:


Dim xMenu1 = <div class="menu">
                <ul id="menu">
                   <%= From node In SiteMap.RootNode.ChildNodes _
                                    .OfType(Of SiteMapNode)() _
                       Select <li class=<%= if(SiteMap.CurrentNode Is node, _
                                               "active", _
                                               "inactive") %>>
                                 <a href=<%= % node.Url>>
                                    <%= helper.Encode(node.Title) %></a>
                     </li> %>
                 </ul>
              </div>
Return xMenu1.ToString()

There are a couple things to point out here. First, the SiteMap.RootNode.ChildNode property returns a list of Object rather than SiteMapNode items. We can fix that by purposely limiting the results and strongly typing it at the same type using the .OfType(Of T) extension method.

Second, We eliminate the for each loop by projecting the new li items in the select clause. In this, we use the ternary If to determine if the node in the iteration is the same as the one selected. If it is, we apply the "active" style. The rest is relatively straight forward.

At this point, we have fixed issues 1 and 4 from my objection list above. Next, let's deal with the n=levels of menu items. To do this, we will replace the LINQ query with a recursive function call. The Menu helper extension now looks like the following:


Imports System.Runtime.CompilerServices

Namespace Helpers
    Public Module MenuHelper
        <Extension()> _
        Public Function Menu(ByVal helper As HtmlHelper) As String
            Dim xMenu = <div class="menu">
                            <ul id="menu">
                                <%= AddNodes(SiteMap.RootNode, helper) %>
                            </ul>
                        </div>
    
            Return xMenu.ToString()
        End Function
    End Module
End Namespace

Now we have an extremely clean and concise XML building of the basic structure. The hard work comes in the AddNodes method.


Private Function AddNodes(ByVal currentNode As SiteMapNode, ByVal helper As HtmlHelper) _
                 As IEnumerable(Of XElement)

   Return From node In currentNode.ChildNodes.OfType(Of SiteMapNode)() _
          Select <li class=<%= If(SiteMap.CurrentNode Is node, "active", "inactive") %>>
                     <a href=<%= node.Url %>><%= helper.Encode(node.Title) %></a>
                     <%= If(node.ChildNodes.Count > 0, _
                          <ul class="child">
                              <%= AddNodes(node, helper) %>
                          </ul>, Nothing) %>
                  </li>
End Function

Essentially this function moves the LINQ projection we did in the original re-write into a separate method. This method takes a SiteMapNode and returns rendered lists of XElements. In addition to generating the HTML for the current node's children, we also check to see if the respective child in turn has  are any child nodes and if so, we create a new unordered list and recursively call back into AddNodes to render those children as well. By using a recursive function, we can handle any level of children nodes that the SiteMap throws at us.

In order to add security trimming, we simply need to add a where clause. The SiteMap contains a non-generic IList that happens to contain strings. To use LINQ on this, we use the .Cast method to turn it into a generic IEnumerable(Of String). With that in place, we can use the .Any extension method to find if any of the roles specified in the SiteMap source meet the criteria where the HttpContext's current user is in at least one of those roles. We'll also check to see if there are no roles specified for that node (which means that it is not trimmed and all users can access the node). Here is the revised body of the AddNodes method:


Return From node In currentNode.ChildNodes.OfType(Of SiteMapNode)() _
       Where node.Roles.Count = 0 OrElse _
             node.Roles.Cast(Of String).Any(Function(role) _
                                            HttpContext.Current.User.IsInRole(role)) _
       Select <li class=<%= If(SiteMap.CurrentNode Is node, "active", "inactive") %>>
                  <a href=<%= node.Url %>><%= helper.Encode(node.Title) %></a>
                  <%= If(node.ChildNodes.Count > 0, _
                      <ul class="child">
                          <%= AddNodes(node, helper) %>
                      </ul>, Nothing) %>
              </li>

That's it. The only thing left is to manage the css styles to handle the fly-outs. You should be able to find plenty of sites that demonstrate how to set that up. If you can thinq of any enhancements to this, let me know.

Posted on - Comment
Categories: MVC - VB Dev Center - VB -

Disable Historical Debugger when using MVC with VS 2010 beta1

I've had a bit of down time between contracts recently and have been taking the opportunity to learn some technologies that I haven't had time to get into before. Since I've read so much about it, I thought I would try out ASP.Net MVC. Since it was just for fun, I figured I'd bite the bullet and try it under VS 2010.

I build a small sample following the tutorials at http://www.asp.net/learn/mvc/, however when I try to run it in VS 2010, the app crashes on me. There's enough "Magic" going on inside MVC, including the routing engine and dynamic loading of the controllers and views that trying to debug MVC is challenging enough when the IDE behaves. When it doesn't it makes life significantly more problematic. Naturally VS hard crashes rather than breaking in my code to let me figure out what's going wrong.

It turns out there wasn't a problem in my code, but rather an issue with MVC and the Historical Debugger which is turned on by default in VS 2010. To fix the issue, open the Option dialog (under Tools - Options) and locate the Historical Debugger tab. Uncheck the "Enable Historic Debugging" option.

Historical Debugging Option Screen

Joe Cartano of the ASP team assures us that this will be fixed in Beta 2, so hopefully this is only a temporary situation. Maybe next time I'll remember to read the release notes completely before banging my head against the wall.

Posted on - Comment
Categories: Visual Studio - MVC -