A new ASP.NET MVC project includes preconfigured Membership, Profile and RoleManager providers right out of the box.  Try it yourself – create a ASP.NET MVC application, crack open the web.config file and have a look. 

First, you’ll find the ApplicationServices database connection:

  1. <connectionStrings>
  2.   <add name="ApplicationServices"
  3.        connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
  4.        providerName="System.Data.SqlClient"/>
  5. </connectionStrings>

 

Notice the connection string is referencing the aspnetdb.mdf database hosted by SQL Express and it’s using integrated security so it’ll just work for you without having to call out a specific database login or anything.

Scroll down the file a bit and you’ll find each of the three noted sections:

  1. <membership>
  2.   <providers>
  3.     <clear/>
  4.     <add name="AspNetSqlMembershipProvider"
  5.          type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
  6.          connectionStringName="ApplicationServices"
  7.          enablePasswordRetrieval="false"
  8.          enablePasswordReset="true"
  9.          requiresQuestionAndAnswer="false"
  10.          requiresUniqueEmail="false"
  11.          passwordFormat="Hashed"
  12.          maxInvalidPasswordAttempts="5"
  13.          minRequiredPasswordLength="6"
  14.          minRequiredNonalphanumericCharacters="0"
  15.          passwordAttemptWindow="10"
  16.          passwordStrengthRegularExpression=""
  17.          applicationName="/"
  18.             />
  19.   </providers>
  20. </membership>
  21.  
  22. <profile>
  23.   <providers>
  24.     <clear/>
  25.     <add name="AspNetSqlProfileProvider"
  26.          type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
  27.          connectionStringName="ApplicationServices"
  28.          applicationName="/"
  29.             />
  30.   </providers>
  31. </profile>
  32.  
  33. <roleManager enabled="false">
  34.   <providers>
  35.     <clear />
  36.     <add connectionStringName="ApplicationServices" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  37.     <add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  38.   </providers>
  39. </roleManager>

Really. It’s all there. Still don’t believe me.  Run the application, walk through the registration process and finally login and logout.  Completely functional – and you didn’t have to do a thing!

What else?  Well, you can manage your users via the Configuration Manager which is hiding in Visual Studio behind Projects > ASP.NET Configuration.

image

The ASP.NET Web Site Administration Tool isn’t MVC-specific (neither is the Membership, Profile or RoleManager stuff) but it’s neat and I hardly ever see anyone using it.  Here you can set up and edit users, roles, and set access permissions for your site. You can manage application settings, establish your SMTP settings, configure debugging and tracing, define default error page and even take your application offline.  The UI is rather plain-Jane but it works great.

image

And here’s the best of all.  Let’s say you, like most of us, don’t want to run your application on top of the aspnetdb.mdf database.  Let’s suppose you want to use your own database and you’d like to add the membership stuff to it.  Well, that’s easy enough. Take a look inside your [drive:]\%windir%\Microsoft.Net\Framework\v2.0.50727\ folder.  Here you’ll find a bunch of files.  If you were to run the InstallCommon.sql, InstallMembership.sql, InstallRoles.sql and InstallProfile.sql files against the database of your choices, you’d be installing the same membership, profile and role artifacts which are found in the aspnet.db to your own database. 

Too much trouble?  Okay. Run [drive:]\%windir%\Microsoft.Net\Framework\v2.0.50727\aspnet_regsql.exe from the command line instead.  This will launch the ASP.NET SQL Server Setup Wizard which walks you through the installation of those same database objects into the new or existing database of your choice. You may not always have the luxury of using this tool on your destination server, but you should use it whenever you can. 

image

Last tip: don’t forget to update the ApplicationServices connectionstring to point to your custom database after the setup is complete.

At the risk of sounding like a smarty, everything I’ve mentioned in this post has been around for quite a while. The thing is that not everyone has had the opportunity to use it.  And it makes sense. I know I’ve worked on projects which used custom membership services.  Why bother with the out-of-the-box stuff, right?   And the .NET framework is so massive, who can know it all. Well, eventually you might have a chance to architect your own solution using any implementation you’d like or you will have the time to play around with another aspect of the framework.  When you do, think back to this post.

Ben Griswold on December 31st, 2009

IIS7 introduced the option to run your application pool as AppPoolIdentity. With the release of IIS7.5, AppPoolIdentity was promoted to the default option.  You see this change if you’re running Windows 7 or Windows Server 2008 R2.  image

On my Windows 7 machine, I’m able to define my Application Pool Identity and then create an associated database login via the SQL Server Management Studio interface.  No problem.  However, I ran into some troubles when recently installing my web application onto a Windows Server 2008 R2 64-bit machine.  Strange, but the same approach failed as SSMS couldn’t find the AppPoolIdentity user.  Instead of using the tools, I created and executed the login via script and it worked fine. 

Here’s the script, based off of the DefaultAppPool identity, if the same happens to you:

CREATE LOGIN [IIS APPPOOL\DefaultAppPool]
FROM WINDOWS WITH DEFAULT_DATABASE=[master]
USE [Chinook]
CREATE USER [IIS APPPOOL\DefaultAppPool] FOR LOGIN [IIS APPPOOL\DefaultAppPool]

Ben Griswold on December 31st, 2009

The best gift under the tree this year? A Sony Blu-ray Disc player:

CropperCapture[1]The BDP-N460 allows you to instantly stream thousands of movies, videos and music from the largest selection of leading content providers including Netflix, Amazon Video On Demand, YouTube, Slacker® Radio and many, many more. Plus, enjoy the ultimate in high-definition entertainment and watch Blu-ray Disc movies in Full HD 1080p quality with HD audio.

The BDP-N460 includes built-in software that makes it easy to connect this player to your existing wireless network.  So I did… I paired the disc player with the recommended Linksys Wireless Ethernet Bridge (WET-610N) and I was streaming the last season of Lost episodes in no time.

Really cool. Highly recommended.

Ben Griswold on December 29th, 2009

Most of the time, I’m the guy who authors the show notes for the Herding Code Podcast.  The workflow is relatively straight-forward: Jon shares the pre-production audio with me, I compete my write up and then ship the notes back to Jon for publishing with the edited audio.  All file sharing is all done with shared folders in the Windows Live Mesh.

The director of my kid’s preschool was looking for a way to access her work computer from her home office.  VPN connection?  Remote desktop?  FTP?  Nope. I installed Windows Live Mesh in a matter of minutes, synchronized a number of folders and she was off and running.  (The neat thing is she’s running a PC in the office and a Mac at home.)

I was using Dropbox before discovering Mesh. Dropbox is still very cool but I’m in and out of Mesh enough that it’s taken over.  Actually I still have a Dropbox folder – it’s just being synched by Mesh now.

If you’re interested in giving Live Mesh a whirl, here’ are the notable links as found on the product’s site:

Good luck!

Ben Griswold on December 28th, 2009

I’ve found myself in this situation with multiple Dell docking stations and multiple Dell laptops running various Windows operating systems.  I don’t know why the docking station stops recognizing my USB mouse and keyboard – it just does.  It’s black magic. 

Dell D/Dock Expansion Station Docking station - PCThe last time around I just starting plugging the mouse and keyboard into the docked laptop directly and went about my business (as if I wasn’t completing missing out on a couple of the core benefits of using a docking station.)  I guess that’s what happens when you forget how you got yourself out of the mess the last time around. 

I had been in this half-assed state for a couple of weeks now, but a coworker fortunately got themselves in and out of the same pickle this morning.  Procrastinate long enough and the solution will just come to you, right?

Here’s how to get yourself out of this mess:

  1. Undock your computer
  2. Unplug your docking station
  3. Count to an arbitrary number greater than 12.  (Not sure this is really required, but…)
  4. Plug your docking station back in
  5. Redock your machine

I put my machine to sleep before taking the aforementioned actions.  My coworker completely shutdown his laptop instead.  The steps worked on both of our Win 7 machines this morning and, who knows, it might just work for you too. 

Ben Griswold on December 23rd, 2009

By default, the ReSharper cache is stored in the solution folder.  It’s one extra folder and one extra .user file.  It’s no big deal but it does clutter up your solution a bit – especially since the files provide no real value.

image

I prefer to store the ReSharper cache in the system Temp folder.  This setting is available by visiting ReSharper > Options > Environment > General.

image

Just update where you’d like to store the ReSharper cache and you’re good to go.  Note, the .user file continues to linger around the solution folder but at least the _ReSharper.SolutionName folder is moved out of sight.

Ben Griswold on December 23rd, 2009

SubText is the engine behind our company blog. With the goal of ensuring a smooth transition between the main website and the blogs, I spent some time tightening up the styles for the aggregate and individual blogs last week.  This required a custom SubText skin and lot of css tweaking.CropperCapture[15]

Though I’ve previously had the SubText source running on my machine, there was no need to update or rebuild the solution in my current case so just went ahead with a local installation using the Microsoft Web Platform Installer (Web PI). 

I just checked the SubText box, provided answers to a few key setup questions (admin user credentials, SubText database, etc) and I was up and running in minutes.  

Once the setup was complete, I was asked if I’d like to launch SubText.  The SubText Installation Wizard picked up where Web PI left off and the setup couldn’t have been easier. 

Web PI provides quick and easy installs for lots of goodies.  Check it out.

Ben Griswold on December 22nd, 2009

Last Wednesday, I took a whopping 15 minutes out of my day and added ELMAH (Error Logging Modules and Handlers) to my ASP.NET MVC application.  If you haven’t heard the news (I hadn’t until recently), ELMAH does a killer job of logging and reporting nearly all unhandled exceptions.  As for handled exceptions, I’ve been using NLog but since I was already playing with the ELMAH bits I thought I’d see if I couldn’t replace it.

Atif Aziz provided a quick solution in his answer to a Stack Overflow question.  I’ll let you consult his answer to see how one can subclass the HandleErrorAttribute and override the OnException method in order to get the bits working.  I pretty much took rolled the recommended logic into my application and it worked like a charm. 

Along the way, I did uncover a few HandleError fact to which I wasn’t already privy.  Most of my learning came from Steven Sanderson’s book, Pro ASP.NET MVC Framework.  I’ve flipped through a bunch of the book and spent time on specific sections.  It’s a really good read if you’re looking to pick up an ASP.NET MVC reference.

Anyway, my notes are found a comments in the following code snippet.  I hope my notes clarify a few things for you too.

  1. public class LogAndHandleErrorAttribute : HandleErrorAttribute
  2. {
  3.     public override void OnException(ExceptionContext context)
  4.     {
  5.         // A word from our sponsors:
  6.         //      http://stackoverflow.com/questions/766610/how-to-get-elmah-to-work-with-asp-net-mvc-handleerror-attribute
  7.         //      and Pro ASP.NET MVC Framework by Steven Sanderson
  8.         //
  9.         // Invoke the base implementation first. This should mark context.ExceptionHandled = true
  10.         // which stops ASP.NET from producing a "yellow screen of death." This also sets the
  11.         // Http StatusCode to 500 (internal server error.)
  12.         //
  13.         // Assuming Custom Errors aren't off, the base implementation will trigger the application
  14.         // to ultimately render the "Error" view from one of the following locations:
  15.         //
  16.         //      1. ~/Views/Controller/Error.aspx
  17.         //      2. ~/Views/Controller/Error.ascx
  18.         //      3. ~/Views/Shared/Error.aspx
  19.         //      4. ~/Views/Shared/Error.ascx
  20.         //
  21.         // "Error" is the default view, however, a specific view may be provided as an Attribute property.
  22.         // A notable point is the Custom Errors defaultRedirect is not considered in the redirection plan.
  23.         base.OnException(context);
  24.  
  25.         var e = context.Exception;
  26.         
  27.         // If the exception is unhandled, simply return and let Elmah handle the unhandled exception.
  28.         // Otherwise, try to use error signaling which involves the fully configured pipeline like logging,
  29.         // mailing, filtering and what have you). Failing that, see if the error should be filtered.
  30.         // If not, the error simply logged the exception.
  31.         if (!context.ExceptionHandled   
  32.             || RaiseErrorSignal(e)      
  33.             || IsFiltered(context))     
  34.             return;
  35.  
  36.         LogException(e); // FYI. Simple Elmah logging doesn't handle mail notifications.
  37.     }