ASP.NET MVC in Action at the Aggileland .Net Users Group tomorrow

Tomorrow, I’ll be traveling to College Station, TX to visit with the .Net Users Group from my alma mater.  The group, started by Noah Coad, continues to be a part of the university experience for those students interested in .Net development.

Url here: http://aggielanddnug.org/dnug/

Title:  ASP.NET MVC in Action (derived from my book)

Abstract:  With the new version of ASP.NET, developers can easily leverage the Model-View-Controller pattern inASP.NET applications. Pulling logic away from the UI and the views has been difficult for a long time. The Model-View-Presenter pattern helps a little bit, but the fact that the view has to delegate to the presenter makes the UI pattern difficult to work with. This session is a detailed overview of the ASP.NET MVC Framework.  It is meant for developers already building systems with ASP.NET 3.5 SP1.

Logistics:

Tuesday, July 14, 2009 12:00 PM

TAMU GSC 101B

Billy Hollis on Silverlight at the Austin .Net User Group tonight

Monday July 13th 5:30pm

Silverlight presented by Billy Hollis

Monthly Meeting

Microsoft Office Austin

9606 N Mo Pac Expy # 200

Austin, TX 78759-5933

07/13/2009 17:30 to 07/13/2009 20:00

Billy Hollis has authored and co-authored many books, including the first  book ever published on Visual Basic .NET and many other .NET oriented books. He’s a frequent speaker at industry events like TechEd, Professional Developer Conference (PDC), VSLive, VSConnections, Patterns and Practices Summit, and many others.

View Larger Map

Billy is a member of the Microsoft Regional Directors, a group of third party luminaries that Microsoft recognizes as having the highest level of expertise in Microsoft technologies. Billy was selected as Regional Director of the Year in 2001. Billy is also a Microsoft MVP (Most Valuable Professional) in Visual Basic. Billy is one of the original members of the INETA speakers bureau. INETA is the International .NET Association of user groups. Through INETA, Billy speaks to user groups all over the country. Billy was selected as a Software Legend in 2002.

Agile Austin talk coming up this next Tuesday – July 7th

I am honored to be the speaker at AgileAustin this next Tuesday on July 7, 2009.  You can see the details of my talk here.

Speaker: Jeffrey Palermo – CTO, Headspring
Title: Being The Manager Of An Agile Team
Description:
Extreme Programming has lots to say about agile software engineering and testing.  Scrum has a lot to say about the process of iterating and organizing priority.  Lean has a lot to say about increasing production and production quality as well as eliminating waste.  Lots of client, even with agile training, still remain with questions about where management fits in within an agile culture.  This session is a blend of project management and people management.  Some of the looming questions surround:

* How to deal with risk
* Predicting issues
* Forecasting
* Hiring and firing
* No broken windows (defects)
* Feedback and metrics
* Managing scope & setting expectations

Additional Information:
Cost: Free
Map & Directions: From South of Hwy 183: Travel North on Mopac (Loop 1) exiting at Capitol of Texas Hwy. Make a U-turn before the traffic light. Go one block on the access road.  Stonebridge Plaza One is to the right, with an entrance between the two towers.  Building One is on the right as you enter.  (map)
More Info:  info@AgileAustin.org
Agenda: Sign-in and Networking 6:00 – 6:30 PM
Announcements, Presentation 6:30 – 8:00 PM
Q&A and Networking 8:00 – 8:30 PM

Proof of Attendance forms will be provided for PMI (PDU), ASQ (RU) and PDMA (PDH) re-certifications

Upgraded to Windows 7 RC – how I kept from reinstalling everything, and what didn’t work

Last night, I downloaded and installed Windows 7 RC.  I installed the Beta for my wife on a spare laptop, and she hated it, so I gave her her Windows XP back. :-).  I have used it for a single day now, and I haven’t encountered any blocking issues.  My process:

  1. Backup disk partition with Acronis True Image Home 2009
  2. Upgrade from Vista x64 to Windows7 x64
  3. Try all critical applications and drivers to ensure they still work
  4. Breath a sigh of relief.

If anything had stopped working, I was prepared to immediately reimage my hard drive with the backup image taken with Acronis (I don’t like to repave machines – big waste of time).

Here is a picture of my new desktop (1900 x 1200) from the Dell 24in monitor.  I have checked the following things I depend on daily and have ensured they still work:

  • Google Chrome
  • Skype
  • Visual Studio 2008 w/ Resharper (I did turn off UAC because it’s still annoying)
  • Tethering Windows Mobile Smartphone through AT&T for mobile internet connection
  • Google Desktop (search and app launching)
  • Pidgin (IM)
  • PortableApps
  • TweetDeck
  • Microsoft Office
  • CCTray
  • And all my diverse hardware

What didn’t work was Syncing my smartphone.  I haven’t dug in, but that doesn’t work at present (Samsung BlackJack II with WM5).

image

Running development from a RAM disk – options and products

In my post about ditching the Solid State Drive in favor of the RAM disk, I mentioned the speed increases.  Taking away the IO bottleneck is significant, and it can let us turn our attention to other bottlenecks that remain.  Here, I am going to outline what I’m currently using, what I’ve tried, and some steps to get it all working.

Workstation specs

If your Windows OS is already paging to disk because of a lack of RAM, then using a ram disk doesn’t make much sense.  You must have unused RAM.  I tried Vista SuperFetch for almost a year, and while it did fill up all available RAM, I still didn’t see the machine fly.  Allocating  a RAM disk with my surplus of RAM did make the machine move much quicker.  I’ve looked at SuperCache and SuperVolume from SuperSpeed, but those products are only offered for Windows XP.  They seem very promising because SuperCache does a delayed write on the entire boot drive and uses RAM as the primary IO resource. 

My workstation (and that of all of my employees) is:  Dell Precision M4300 laptop (2.x GHz dual core proc, 8 GB RAM, Seagate 7200 hard drives)

I was able to get 4GB RAM sticks from memory-up.com for less than $160 each.

Products

I tried out SuperSpeed RamDisk Plus as well as DataRam RAMDisk.  Both products can support the size of the RAM disk that I need (3GB).  Both products automatically persist the contents of the RAM disk to the hard drive upon shutdown and restart, so there is a seamless experience with both.  Because I’m using these in a laptop scenario, a sudden power outage is unlikely, and all the stored files are working copies of Subversion, where commits happen multiple times per day.

Decision

Ultimately, I’m currently running DataRam RAMDisk not because I see it as materially superior to SuperSpeed’s product, but because it gives me what I need for a lower investment.  RamDisk Plus gives me much more than I need; therefore, I would be paying for unneeded features.  I used both, and both are easy to use.  RamDisk Plus is about $100 for a Vista x64 license, and DataRam’s RAMDisk is free for the size I need, which is <= 4GB.  You have to pay for larger.

Ramdisk Screenshot

With DataRam RAMDisk, you can format it yourself, so that’s what I did by formatting it as NTFS with Disk Manager.  You can see that I’ve mapped a 3GB RAM disk to the R: drive.

image

I have also mounted it inside the C: drive so that I can access it quickly from WINDOWS+R:

image

I did this through the Disk Manager’s mount points:

image

My final step was to set SQL Server to use the RAM disk as its disk for newly-created databases.  Our line-of-business applications are IO intensive including database interaction, and the automated tests are especially so.

 image

All-in-all, the setup is pretty simple regardless of which RAM disk product is used.  I love the speed improvement it has given the workstations.  Obviously running less stuff in an automated build will make it run faster, but there are some things that just MUST be run in a first-line build, and that build must remain fast.  Besides the build, even compilation and working inside Visual Studio is quicker because all of the files are in RAM.

Need certified ScrumMaster for a project immediately – send me a note

I have a year-long contract for a capable ScrumMaster.  If you have been a programmer, that is a plus but not necessary.  This is for a government client of ours.  Send me a note using the contact form or respond to jobs [at} headspringsystems.com

Austin, TX candidates only.   Will not pay for travel.

The ASP.NET MVC ActionController – The controllerless action, or actionless controller

There has been quite  a bit of discussion about how controllers are really namespaces trying to get out once you use the concept on a nontrivial application. 

Brian Donahue’s post on The anti-controller revolution prompted me to do this little experiment.  He references some twitter posts by Jimmy Bogard, one of my esteemed consultants at Headspring Systems.  Chad Myers also has opined about the notion of more independent actions and has cited precedence.

My interest in this space is purely practical.  I really don’t care how patterns are published.  I don’t care about “being true” to the MVC pattern or any other pattern.  I’m more interested in being effective with web applications on .Net.  After having experience with MvcContrib, CodeCampServer, and a much larger ASP.NET MVC implementation (200+ screens), I have come to see how controllers end up searching for an identity.  What is a ProductController anyway?  That’s just about as specific as classes called ProductService, ProductManager, ProductUtility, etc. 

Overview

You can SVN checkout the following url to see my spike code:  https://palermo.googlecode.com/svn/actioncontroller/trunk.  You can get it in zip file format here. (I repeat these links below)

In the default ASP.NET MVC project template, there is a HomeController, and then there is an AccountController that hooks up the ASP.NET MembershipProvider.  The AccountController does registering, logging in/out, changing password, and it is WAY too big.  The AccountController lacks cohesion.  The AccountController has more than one reason to change.  Each of the actions seem like they are more cohesive.

I’m going to narrate a before and an after of the ASP.NET MVC default project as I refactored it into being a ActionController-based application.  The controller names were promoted to namespaces and the action names were promoted to controller names.  The requests for a GET and POST of the same url are handled by the same ActionController since the action name is the same.  There are two methods in the class; one that handles GET and one that handles POST.  Within the ActionController, the methods are named “execute” since the name of the action is in the class name.  View structure stayed the same.  Seems there isn’t much pain in the view structure.

Routes

Let’s look at the possible URLs in the default project:

  • / (GET)
  • /Home/About (GET)
  • /Account/LogOn (GET)
  • /Account/LogOn (POST)
  • /Account/Register (GET)
  • /Account/Register (POST)
  • /Account/ChangePassword (GET)
  • /Account/ChangePassword (POST)
  • /Account/ChangePasswordSuccess (GET)

Throughout my refactoring, the urls do not change.  The routes do not change.  The only thing that changes is that the controllers are broken up into multiple classes along action lines.  For instance, There are two LogOn actions.  One for the form rendering, and one to accept the post.  These two are cohesive together, but they are not cohesive when combined with register, like they are by default with the AccountController.

Before

image  Let’s start at the beginning.  To the top (MvcApplication2) is the default project with no modification.  You can check out the code yourself.  The HomeController is pretty easy to dissect, but the Account controller is responsible for 7 independent requests.  5 too many, I think. 

After

imageTo the top(MvcApplication1), we have what the project ended up looking like after the refactoring.

You can see that the actions from the AccountController were promoted to be controllers. 

Let’s take a look at the LogOnController.  I have pushed the two Execute methods to the top for clarity.  With ActionControllers, the controller is only concerned about one action.  In this case, the GET pass of the action renders a form, and the POST pass of the action modifies some server state.  Here is the code:

Sample ActionController

namespace MvcApplication1.Controllers.Account
{
public class LogOnController : ActionController
{
public ActionResult Execute()
{

return View();
}



[AcceptVerbs(HttpVerbs.Post)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
Justification = "Needs to take same parameter type as Controller.Redirect()")]
public ActionResult Execute(string userName, string password, bool rememberMe, string returnUrl)
{

if (!ValidateLogOn(userName, password))
{
return View();
}

FormsAuth.SignIn(userName, rememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("", "Home");
}
}



public LogOnController()
: this(null, null)
{
}

// This constructor is not used by the MVC framework but is instead provided for ease
// of unit testing this type. See the comments at the end of this file for more
// information.

public LogOnController(IFormsAuthentication formsAuth, IMembershipService service)
{
FormsAuth = formsAuth ?? new FormsAuthenticationService();
MembershipService = service ?? new AccountMembershipService();
}

public IFormsAuthentication FormsAuth
{
get;
private set;
}

public IMembershipService MembershipService
{
get;
private set;
}

private bool ValidateLogOn(string userName, string password)
{
if (String.IsNullOrEmpty(userName))
{
ModelState.AddModelError("username", "You must specify a username.");
}
if (String.IsNullOrEmpty(password))
{
ModelState.AddModelError("password", "You must specify a password.");
}
if (!MembershipService.ValidateUser(userName, password))
{
ModelState.AddModelError("_FORM", "The username or password provided is incorrect.");
}

return ModelState.IsValid;
}

}
}

What’s at the heart of this, you might think?  There are two things:

  1. A Custom controller factory (to find the right ActionController)
  2. A controller base class, “ActionController”

Download

I spiked out an implementation of the ActionController.  This is completely non-vetted in a real environment, but the sample project is available for download here. (http://palermo.googlecode.com/files/ActionController.zip)  This includes an ASP.NET MVC project with the ActionController class.  You can SVN co here:  https://palermo.googlecode.com/svn/actioncontroller/trunk

Please download the code and check it out.  What it ends up doing for the actions is groups them cohesively and then the concept of the “controller” becomes a namespace.  The controller factory needs work to be able to locate ActionControllers that are unique within the controller namespace but not unique throughout the project.  This is a rough first pass that I did in 30 minutes.

I’m not sure if this is what I’ll commit to MvcContrib for more widespread consumption, but I (and my teams) are feeling a bit of pain with bloated controllers, so it’s worth considering.  What I like most about this approach is that the only thing that changed was the controllers.  The routes don’t change.  The view folder structure doesn’t change.  The Html helpers don’t change.  We merely refer to the concept of a controller as a namespace rather than a class.  We now refer to an action as a class instead of a method.