Category Archives: Code

Visual Studio Online’s build: Azure Powershell fail the build

visual_studio_online_build_tasks

Visual Studio Online has many tasks: tasks for building .NET solutions, tasks for building Android, tasks for running bash scripts, tasks for running batch files.  If you want to run in the context of your Azure subscription, you use the Azure Powershell task.  I use this task to do some funny footwork in deploying successful results to an Azure Web App.

The problem:

& $env:BUILD_SOURCESDIRECTORY\the.exe
$e = $LASTEXITCODE
Write-Host "Exit code: $e"
exit $e

So I’m cruising along, my exe returns a non-zero status code to mean “please fail the build”, and Visual Studio Online happily succeeds.  I’m clearly returning 1 from my Azure Powershell task, but it’s not getting the message.

A few hours of pulling out grey hairs, and I’m given a great gift from Chris Patterson.  (Scott Hunter: your team rocks.)  Turns out that the Azure Powershell task isn’t run from powershell.exe, so it doesn’t harvest exit codes.  The solution was simple once he handed it to me.

The Solution:

& $env:BUILD_SOURCESDIRECTORY\the.exe
$e = $LASTEXITCODE
Write-Host "Exit code: $e"
if ($e -ne 0) {
    Write-Error -Message "##[error]BUILD FAILED: $e"
}
exit $e

By using Write-Error, the build correctly fails when it needs to, and life is good.  Chris mentions that he’d like to see it work differently, but it didn’t make RTM.  If you’d like this idea to come in-the-box, vote up my Pull Request … because the task is open-source.  Awesome!

Azure Websites Git Deploy Fail

Windows Azure Here’s an interesting fail.  I’m at the Windows Azure Developer Camp practicing some Git Deploy (total win!), and I hit a very interesting snag.  I’m deploying a legacy .net 3.5 app, and “git push azure master” failed with an http 500.  No other message.  Enter head-scratching mode.  Is it that it’s using a Windows Azure SQL Database?  Did I typo the connection string?  Did I put an unusual character in the site name?  Did I typo the deployment credentials?  Is my machine controlled by aliens?

A few rounds of thrashing ensued where I reset deployment credentials, validated the git remote url, typed credentials painstakingly carefully, and still the same result: “http 500.”  Next round: I deleted and recreated the Azure Website (simpler name), switched to .net 3.5 in the Azure Portal, ran git deploy, and fail again.  Crap.  Well, rule out typo or bad character.

On a whim I switched it to .net 4.5 in the portal, and git deploy succeeded.  (Of course my site is now toast because it isn’t a .net 4.x site, but it’s now deployed.  Switch back to .net 3.5 and the site springs to life though.)  Ok, this is curious.  I flipped another dozen switches before I found the solution: git deploy fails when the site is set to 3.5 in the Azure Portal.  This is quite repeatable.  Changing nothing else, I set to 4.5, git push azure master succeeds.  I set it to 3.5, git push azure master fails with 500.

I know nothing of the internals here, but wondering aloud with Michael Palermo, I’m guessing perhaps Kudu‘s git mechanism links against libgit2’s .net bindings, and that exe is a 4.x app.  Perhaps when IIS is set to 3.5, the deployment also runs in 2.x/3.x mode, and this 4.x deployment app fails.

Ultimately, I got past the problem, and were I to make a serious move here, I’d just recompile in .net 4.5.1 and be done.  And more than likely if I’ve embraced the cloud to the point that I’d git deploy into production, I’ve also embraced .net 4.5.  But for that interesting edge case where I am git deploying .net 3.5, should it fail in such an obscure and undiscoverable way?  That’s where the real head-scratching begins.  :D

IIS Web Server Best Practices

Best practices I use when setting up IIS:

– Each site should be a separate (sub-)domain.  Thus http://somesite.mycompany.com/ instead of http://www.mycompany.com/somesite/  This solves a few problems: “../../don’t/do/this.jpg” is avoided when you can presume the root of your site is “/”, which means you can avoid relative paths (even if you need not crawl up a directory) and you can avoid the ~.  It’s much cleaner all the way around.

– Because each site is its own (sub-)domain, you also avoid the pitfall of virtual directories.  A virtual directory is an app within an app.  (http://www.mycompany.com/otherapp/) and some changes to the outer app cascade into the inner app.  For example url rewrite rules, authentication, dll mapping, etc.  Basically the system starts at your app’s directory’s web.config, crawls up the folder stack layering behind every web.config it finds, layers behind that the web.config in the framework directory, and finally machine.config.  This is why you need not copy every changes in your regular web.config into the web.config in the Views folder in MVC.  Because a virtual directory is by definition an app inside another app, of necessity you’ll inherit the outer app’s web.config, potentially negatively impacting your app as their app evolves.

– The app pool is the execution space, so, each site should have its own.  That doesn’t completely protect you from another site blowing up your site, but it does help considerably.  Especially if a technician needs to recycle the app pool as part of an app upgrade or if only one site on the machine is having troubles.

– If you consistently change things on all sites like removing headers, configuring additional mime-types, rearranging or removing default document names, setting the error pages, etc, do these on the machine node in IIS rather than redundantly for each site.

ASafaWeb.com is a great tool for highlighting configuration errors and places where you’re exposing more information than necessary.

– Make sure you handle the “naked domain” (zone apex).  Mapping to www.mysite.com is important, but users could just as easily hit mysite.com (without the www) and if your site doesn’t handle both, a consistent portion of your users will consider your site “broken”.  For SEO purposes, permanently redirect one to the other.  (Which you choose is likely a matter of corporate culture or preference, and ultimately is irrelevant … provided you consistently choose it in IIS configurations, Google Webmaster Tools, etc.)

– If at all possible, run the apps in the most recent framework version, in “Integrated” mode, with 32-bit disabled, with modern .net frameworks installed on the box, and all Windows Updates.  Ideally you’ll also be on the most modern OS version too.  Your apps may need code changes to make this possible.  These are the defaults with new installs and are promoted as “modern techniques” [read: best practices], and ensuring your apps are compliant suggests future deployments to similar or newer hardware or OSs will be less traumatic.

– c:\inetpub\wwwroot\myapp is a very awful place to put your web site folder.  Because this is the default, if I’m a hacker trying to compromise your site and I find another way into your box (FTP, RDP, network share, etc) I can stick something in all such folders and compromise every site on the box.  Script kiddies have automated attack tools that can do this.  Instead, I create a folder like C:\Internet\ or C:\Websites\ or similar.  Inside, I have a folder for each site with sub-folders for:

  • db
  • logs
  • www

I’ll then put the IIS website content in the www folder, point IIS to put the site’s logs into the logs folder, (Ever crawl through IIS’s default log folder trying to figure out which log folder you want?  I’m sorry, “W3SVC6” is not sufficiently descriptive.) and if SQL Server is on the same machine (not best practice), point it to put the mdf and ldf files into the database folder.  Now when you want to backup “everything”, just stop IIS, stop SQL, and copy C:\Internet.  You got “everything” for all sites on the box (with the exception of C:\Windows\System32\inetsrv\config\applicationHost.config which you should also backup periodically.)

– applicationHost.config is not scary.  It’s the “Metabase” (using IIS 6’s term) and is just an xml file.  From time to time, IIS’s GUI has a wacky limitation or I want at it faster than that, so I just pop open C:\Windows\System32\inetsrv\config\applicationHost.config using an elevated notepad and hack away.  Want to setup the second server in the farm to exactly match the first?  Install IIS, install all the plugins you need via Web Platform Installer, run windows update a few times, then use Beyond Compare or WinMerge to diff old box’s applicationHost.config to new box’s, and copy across.  Ta-da!  Instant second box.  (BTW, don’t copy over the “encryption key” lines nor module or handler lines for plugins you didn’t install, and make careful backups before changing this file.  Either that, or you can get good at reformatting boxes.  I needed only make that mistake once.  :D)  Of particular interest in applicationHost.config is the <sites> node.

– One of the big challenges with IIS is “who owns the site’s web.config: The IT dept or developers?”  This is because site-specific changes made in IIS are stored in the app’s web.config.  (This is also why php and node apps hosted on windows have a web.config file even though they don’t use .net.) Alter the list of default documents or change the authentication scheme, and it’ll write these nodes into web.config.  On next deploy if you flush and reset everything — including web.config — you’ll remove these settings.  Oops.  (Also see the “if you do it on every site, do it to the box not to each site” note above.)

– The remote management service is incredibly cool.  http://www.iis.net/learn/manage/remote-administration/remote-administration-for-iis-manager  Typically the only reason we RDP to the IIS machine is to use IIS Manager, run windows updates, or figure out why it ran out of hard drive space.  It is an increased attack surface to have the management service on, so perhaps configure the firewall to only expose port 8172 (or the one you configure) to the LAN and not to the public.  Now no more RDPing for config changes.

I’m confident this is hardly an exhaustive list, but based on these, you can get to a pretty good place in IIS, and probably get the Google-fu cranked up too.  Happy hosting!

Rob

Git on-premise hosting

All else being equal, you should use GitHub (http://www.github.com/) for Git hosting.  GitHub is indeed a cloud-hosted git repository, but it’s so much more than that.  It has integrated issue tracking, comment on any line of any commit (social coding), and pull request (e.g. “will you please review and pull my content”).  It’s truly a revolution in source control, and there’s really nothing like it.

If you’re forced into an on-premise solution, the natural draw is to facilitate “Git Smart HTTP” in IIS.  Git has native Apache bindings, but doesn’t have anything native for IIS, so there’s a plethora of home-grown answers.  The field is ripe for someone like Visual SVN to come through and make a good, GUI-driven Git webhost, though even Visual SVN is technically Apache.  You can use Git without http hosting as well (same as with SVN), though http hosted git servers are cool.  :D

I use WebGit.NET: https://github.com/otac0n/WebGitNet/wiki/Getting-Started  It has no built-in authentication, but none of these really do.  http://serverfault.com/questions/369573/what-iis-authentication-method-to-use-with-git-server-hosted-on-iis has some descent ideas on how to secure it, but all add weight to each repository access operation.  I chose instead to only bind to 127.0.0.1, so you’d need to be physically on my machine to get to the site, and if you’re that far, you may as well be in my repository.  You could do something similar by exposing it only to the LAN (and by extension VPN users).

If I was to do it again, I’d investigate kudu: http://blog.davidebbo.com/2012/06/introducing-open-source-engine-behind.html and http://blog.davidebbo.com/2012/06/developing-kudu-locally-and-on-azure.html  It’s what Microsoft built for Azure git deployment.  But as part of that, it has a git web engine that may be useful separately.  It has one IIS site for administration, and a second for repository access.  That’s a bit weird, but it does mean you can secure them separately.

Other popular IIS-hosted Git solutions include:

– GitWebAccess: http://gitweb.codeplex.com/  I used this one for a time.

– GitDotNet: http://www.jeremyskinner.co.uk/2010/06/25/hosting-a-git-server-under-iis7-on-windows/  The author recommends against his solution.

– GitAspx: http://www.jeremyskinner.co.uk/2010/10/19/gitaspx-0-3-available/

– Bonobo: http://www.chodounsky.net/bonobo-git-server/  I recall looking at it early on, but don’t recall why I didn’t like it.  Perhaps it’s due a second look.

– GitStack: http://gitstack.com/gitstack-and-other-web-servers/  If I remember correctly, this is a paid installer of some cobbled open-source tools.

– SCM Manager: http://www.helicontech.com/articles/hosting-git-svn-and-hg-mercurial-repositories-on-windows-with-iis/  It does SVN, Mercurial, and Git as a Java website.

http://stackoverflow.com/questions/51619/how-to-setup-git-bare-http-available-repository-on-iis-machine includes some more.

Rob

Moving to IIS Express and https

I’ve been asked a few times to help people move from their current use of the Web Development Server to https. This requires one also move to IIS Express as the old Web Development Server (Cassini) doesn’t support https. Here’s a brief tutorial on making the changes. This will allow you to test the sites using a very similar mechanism to a production deployment. We’ll also discuss certificates and Fiddler concerns.

Step 1: Setup

Get your environment setup:

  1. Startup Visual Studio, and load the target project and/or solution

Step 2: Configure IIS Express

For each website you’d like to convert to IIS Express and https:

  1. In the Solution Explorer, right-click on Web project, and choose “Use IIS Express” (just under “Set as Startup Project”)  NOTE: If you don’t have this option, you don’t have Visual Studio 2010 Service Pack 1 installed. Install VS 2010 SP 1 then retry this procedure.
  2. Go to the project properties by right-clicking the project, and choosing properties at the very bottom.
  3. In the Web tab, choose “Use Local IIS Web Server” and check “Use IIS Express”. Set the Project Url as necessary.
  4. Ensure “Apply server settings to all users” is unchecked. If this is checked, these changes will be inflicted on all users of the solution including any user-specific derivations (such as the location of your solution).
  5. Enable SSL by selecting the project in the Solution Explorer, switching to the Properties window, and setting “SSL Enabled: True”. You will be assigned a random port, probably localhost:44300, but you can’t change that here.

Step 3: Change IIS Express SSL Ports

  1. Close Visual Studio so it doesn’t get confused as we change IIS Express files.
  2. Open The IIS Express configuration file in your favorite text editor such as Notepad. It is in a path similar to C:Users{myusername}DocumentsIISExpressconfigapplicationhost.config
  3. Scroll down to the <sites> node.
  4. Alter the bindings lines for each of the sites to include your preferred ports.
  5. Save and close the file.

Step 4: Update the Project’s port if necessary

Back inside Visual Studio, we’ll tweak the last few things, and we’ll be ready to roll:

  1. Startup Visual Studio, and load the target project and/or solution
  2. Go into the project’s settings: Solution Explorer -> right-click on project -> Properties at the very bottom -> Web tab
  3. Update the Project Url if necessary to match the details you set in applicationhost.config

Step 5: Update configuration values

If your project uses any configuration values that reference the site url or port, you’ll need to update them to point to the new https url.

Step 6: Try it Out

We’re ready to roll:

  1. Debug the target project / solution
  2. In your browser, go to the https url you specified (example: https://localhost:44300/)

It works, but you’ll quickly discover failures because the cert isn’t trusted.

You’ll also notice that IIS Express binds specifically to “localhost:port#”, and doesn’t listen on “localhost.:port#”. (Note the dot in the second url.) Adding this dot is a great tool for debugging with fiddler as it makes the browser use DNS to resolve the site, which happily makes it use the configured proxy – Fiddler. Without this dot, it’s really easy to make web requests and get absolutely nowhere. Unfortunately, this no longer works with IIS Express. Sadly, you’ll need to remove the dot.

Step 7: Trust IIS Express Certificate in your chosen browser(s)

Unfortunately, Chrome will use the local certificate store, but has no way to alter the local certificate store, so we must use Internet Explorer to configure the certificate trust. These steps are pulled from http://stackoverflow.com/questions/681695/what-do-i-need-to-do-to-get-internet-explorer-8-to-accept-a-self-signed-certific and http://productforums.google.com/forum/#!topic/chrome/bds-Ao9LigA. The former (quoted here) shows you how to get IE (and thus .NET) to trust the self-signed certificate, the latter, targeted towards Chrome, puts the certificate in “Third-party Certificate Store” instead of “Trusted Root Certification Authorities”.

How to make IE8 trust a self-signed certificate in 20 irritating steps: (source: http://stackoverflow.com/questions/681695/what-do-i-need-to-do-to-get-internet-explorer-8-to-accept-a-self-signed-certific)

  1. Browse to the site whose certificate you want to trust.
  2. When told “There is a problem with this website’s security certificate.”, choose “Continue to this website (not recommended).”
  3. Select Tools->Internet Options.
  4. Select Security->Trusted sites->Sites.
  5. Confirm the URL matches, and click “Add” then “Close”.
  6. Close the “Internet Options” dialog box with either “OK” or “Cancel”.
  7. Refresh the current page.
  8. When told “There is a problem with this website’s security certificate.”, choose “Continue to this website (not recommended).”
  9. Click on “Certificate Error” at the right of the address bar and select “View certificates”.
  10. Click on “Install Certificate…”, then in the wizard, click “Next”.
  11. On the next page select “Place all certificates in the following store”.
  12. Click “Browse”, select “Trusted Root Certification Authorities”, and click “OK”.
  13. Back in the wizard, click “Next”, then “Finish”.
  14. If you get a “Security Warning” message box, click “Yes”.
  15. Dismiss the message box with “OK”.
  16. Select Tools->Internet Options.
  17. Select Security->Trusted sites->Sites.
  18. Select the URL you just added, click “Remove”, then “Close”.
  19. Now shut down all running instances of IE, and start up IE again.
  20. The site’s certificate should now be trusted.

After this procedure is done, Chrome will note that the url is “localhost”, that it isn’t routable across the internet, and thus it is impossible for a trusted certificate store to issue such a certificate. It will also note that the certificate’s domain and page’s domain match, and will no longer prompt you to “proceed anyway”.

Step 8: (Optional, Advanced) Use IIS instead of IIS Express

Getting IIS Express to start when you begin debugging and stop when you end debugging is very, very handy. But there are times when you’ll want to use the site but don’t want to have to launch Visual Studio first – e.g. to demo the project to a potential client. In that case, you can use the full IIS 7.5 installed in Windows instead of IIS Express with these modifications:

Configure the project to use IIS:

  1. Right-click on the project in Visual Studio, choose properties, switch to the Web tab, and uncheck “Use IIS Express”.
  2. Change the Project Url to use your chosen IIS url.

Install IIS 7.5 on Windows 7 (if it isn’t there already):

  1. Start -> Control Panels.
  2. On the left, choose “Turn Windows Features on or off”.
  3. Inside Internet Information Services, inside Web Management Tools, check on IIS Management Console.
  4. Inside Internet Information Services, inside World Wide Web Services, check on at least ASP and ASP.NET.
  5. Troll through the other settings inside Internet Information Services, checking on anything that looks interesting.
  6. Ensure WebDAV is /NOT/ installed: Internet Information Services -> World Wide Web Services -> Common HTTP Features -> WebDAV Publishing to off. You likely don’t need it, and it’s a great security hole.
  7. Ensure FTP is /NOT/ installed: Internet Information Services -> FTP must be off. Same thing, reduce the attack service.

Configure IIS:

  1. Start -> Administrative Tools -> Internet Information Services. NOTE: If you don’t have this option, you need to first install IIS.
  2. Right click on Sites, and choose Add Website.
  3. Add the website details.
  4. Click Application Pools, and ensure the app pool settings are appropriate to your use.
  5. If any of the settings for the App Pool aren’t as specified, choose the app pool, click “Basic Settings…” on the right, and alter as needed.

Both Forms Authentication and Basic Authentication

The question was asked:

Given an asp.net application that in itself uses Forms Authentication, what is the best practice for securing a public-facing demo site such that nobody who is not in the “in crowd” can see the site at all?

My answer was pretty cool, and I wanted to remember it someday when I had a similar question.  Up-vote it if you too think it’s cool:

Typically the “demo sites” are secured with Basic Authentication.  e.g. return a 401 to the browser with a basic authentication challenge that it turns into prompting for credentials.  In theory, once this is done, the rest of the site is just regular stuff — forms auth when needed.

The difficulty with this approach in ASP.NET comes in the fact that the default FormsAuthenticationProvider is hard-wired to interpret a 401 as “need to 302 to the login page.”  With that as a premise, getting both Forms Authentication and Basic Authentication to happen simultaneously is a challenge.

Also, the Basic Authentication built-in to IIS uses Windows as the authentication store (Active Directory or local windows accounts.)  Getting it to use a different credential store is not easy to do “in the box”.

http://custombasicauth.codeplex.com/ is a project I’ve been watching that is quite intriguing.  It provides a custom Basic Authentication provider that allows you to rig up Basic Authentication from a different provider store.  Pop open the source to http://custombasicauth.codeplex.com/SourceControl/changeset/view/53965#183990 and http://custombasicauth.codeplex.com/SourceControl/changeset/view/53965#183995 and see that they’re just extracting the Base64-encoded header, and comparing it to an ASP.NET Membership Provider.  With that as a premise, you could rig up a similar HttpModule to compare the header data to a user/pass stored in AppSettings, and include the module in your demo site.  The magic sauce is that you don’t set the 401 status on Authenticate, you do so at EndRequest — after the FormsAuthenticationModule has finished it’s “401 to 302 to login page”.  The only down-side is the <location> tags have to be used by Forms Auth or by Basic Auth, but not both.  If the use-case is truly “secure the entire demo site”, then it’s sufficient to code the Basic Auth module to “just do it all”.  I’m about 2/3 of the way doing exactly this.  When I’m done, I’ll likely post it to GitHub as it’s turning out pretty cool.  Alas, the technique isn’t that hard, and perhaps the description of the solution is sufficient.

And if you really want a hands-off, no-code solution, install http://custombasicauth.codeplex.com/.  It even gives you pretty config windows in IIS.  :D 

Elmah: return the ErrorId from Signal.Raise()

ELMAH is an awesome error logging framework for ASP.NET.  It provides both an elegant way of capturing errors, and an elegant way of displaying them later.  It’s available as a NuGet package, and is both Web Forms and MVC friendly.

Generally, Elmah “just works” and you can walk away happy as a clam.  But there’s times where you want to do custom error logging.  The general solution is to do something like this:

ErrorSignal.FromContext(HttpContext.Current).Raise(ex, HttpContext.Current);

The up-side is you can log anything you want then gently recover.  The down-side is you can’t get the logged ErrorId.  Granted, based on your Elmah filters, maybe it wasn’t logged.  But if it was and that location stores an id (see Elmah’s SqlErrorLog) then it’d be really nice for Raise() to return that Id.

The problem is elegantly described http://code.google.com/p/elmah/issues/detail?id=148 and http://stackoverflow.com/questions/7895271/getting-the-id-of-an-error-in-elmah-after-calling-raise/7902138 with nearly identical results: “You can’t get there from here, don’t bother.”

The closest work-around is to listen to the ErrorLogModule’s Logged event, and shim it to where you need it:

void ErrorLog_Logged(object sender, ErrorLoggedEventArgs args) {

     string key = args.Entry.Id;

     // stash this somewhere

}

Then after the .Raise() call, you pull it from the stash location.  HttpRequest.Items is request-specific cache, and provides a descent stash location.  But this is at best a fragile hack.

As any good programmer would say, this is a problem that can easily be solved with code.  I downloaded the Elmah source, made some quick adjustments, and posted the solution to http://code.google.com/p/elmah/issues/detail?id=148#c3.  On the off chance that post gets deleted and to add more visibility to the simplicity to the solution, here’s the patch file that shows the (not kidding) 14 lines that made this feature a reality.  If you like this patch too, log into Elmah’s project site and “me too” comment to the ticket.

diff -r 2482ebd0a4ae src/Elmah/ErrorLogModule.cs

— a/src/Elmah/ErrorLogModule.cs    Tue May 01 19:31:20 2012 +0200

+++ b/src/Elmah/ErrorLogModule.cs    Wed May 02 16:13:53 2012 -0700

@@ -84,15 +84,21 @@

 

         protected virtual void OnErrorSignaled(object sender, ErrorSignalEventArgs args)

         {

–            LogException(args.Exception, args.Context);

+            string id = LogException(args.Exception, args.Context);

+            if (!string.IsNullOrEmpty(id)) {

+                args.ErrorId = id;

+            }

         }

 

         /// <summary>

         /// Logs an exception and its context to the error log.

         /// </summary>

+        /// <returns>ErrorId, may be null since not all errors are logged</returns>

 

–        protected virtual void LogException(Exception e, HttpContextBase context)

+        protected virtual string LogException(Exception e, HttpContextBase context)

         {

+            string id = null;

+

             if (e == null)

                 throw new ArgumentNullException(“e”);

 

@@ -105,7 +111,7 @@

             OnFiltering(args);

            

             if (args.Dismissed)

–                return;

+                return id;

            

             //

             // Log away…

@@ -118,7 +124,7 @@

                 Error error = new Error(e, context);

                 ErrorLog log = GetErrorLog(context);

                 error.ApplicationName = log.ApplicationName;

–                string id = log.Log(error);

+                id = log.Log(error);

                 entry = new ErrorLogEntry(log, id, error);

             }

             catch (Exception localException)

@@ -137,6 +143,8 @@

 

             if (entry != null)

                 OnLogged(new ErrorLoggedEventArgs(entry));

+

+            return id;

         }

 

         /// <summary>

diff -r 2482ebd0a4ae src/Elmah/ErrorSignal.cs

— a/src/Elmah/ErrorSignal.cs    Tue May 01 19:31:20 2012 +0200

+++ b/src/Elmah/ErrorSignal.cs    Wed May 02 16:13:53 2012 -0700

@@ -46,15 +46,19 @@

             Raise(e, null);

         }

 

–        public void Raise(Exception e, HttpContextBase context)

+        public string Raise(Exception e, HttpContextBase context)

         {

             if (context == null)

                 context = new HttpContextWrapper(HttpContext.Current);

 

             ErrorSignalEventHandler handler = Raised;

 

+            ErrorSignalEventArgs args = new ErrorSignalEventArgs(e, context);

+

             if (handler != null)

–                handler(this, new ErrorSignalEventArgs(e, context));

+                handler(this, args);

+

+            return args.ErrorId;

         }

 

         public static ErrorSignal FromCurrentContext()

@@ -154,6 +158,11 @@

             get { return _context; }

         }

 

+        /// <summary>

+        /// When you handle the signal, update this with the resulting ErrorId (if any)

+        /// </summary>

+        public string ErrorId { get; set; }

+

         public override string ToString()

         {

             return Mask.EmptyString(Exception.Message, Exception.GetType().FullName);

diff -r 2482ebd0a4ae src/Elmah/ErrorTweetModule.cs

— a/src/Elmah/ErrorTweetModule.cs    Tue May 01 19:31:20 2012 +0200

+++ b/src/Elmah/ErrorTweetModule.cs    Wed May 02 16:13:53 2012 -0700

@@ -129,15 +129,20 @@

 

         protected virtual void OnErrorSignaled(object sender, ErrorSignalEventArgs args)

         {

–            LogException(args.Exception, args.Context);

+            string id = LogException(args.Exception, args.Context);

+            if (!string.IsNullOrEmpty(id)) {

+                args.ErrorId = id;

+            }       

         }

 

         /// <summary>

         /// Logs an exception and its context to the error log.

         /// </summary>

 

–        protected virtual void LogException(Exception e, HttpContextBase context)

+        protected virtual string LogException(Exception e, HttpContextBase context)

         {

+            string id = null;

+

             if (e == null)

                 throw new ArgumentNullException(“e”);

 

@@ -150,7 +155,7 @@

             OnFiltering(args);

            

             if (args.Dismissed)

–                return;

+                return id;

 

             //

             // Tweet away…

@@ -240,6 +245,8 @@

 

                 OnWebPostError(request, localException);

             }

+

+            return id;

         }

 

         private void OnWebPostError(WebRequest request, Exception e)

Design Patterns for data persistence: Unit-of-Work Pattern and Repository Pattern

Design Patterns

Design Patterns are names we give code constructs.  We’re not usually inventing anything new, we’re just giving a name for things we’ve always done.  You’ve probably been doing it this way forever, but you never knew what to call it, it was just “the way it’s done”.  Giving it a name is very powerful as it gives us a way to communicate about larger topics.  Yeah, we can talk about for-loop, if-block, but what about system architecture topics?  In the world of auto repair, they have names for their larger pieces: radiator, engine block, alternator.  How do you convey to someone how your Data Access tier or your Presentation tier works?  This is the magic of Design Patterns — names for these common execution techniques.

Today we’ll discuss two common Design Patterns for working with data storage: the Unit-of-Work Pattern, and the Repository Pattern.

Unit-ofWork Pattern

Microsoft really likes the Unit-of-Work Pattern, so most every sample you see coming out of their shops will include this pattern.  The general theory is you have a reference to a stateful link to your data store — a Data Context — that will queue up your queries and then execute all the steps at once within a transaction.  They’ll either all succeed or they’ll all fail.

For example you’re placing an order in an Order Entry system.  You may insert or update the Customer record, insert an Order header, insert one or more Order detail lines, perhaps update the product’s available count.  You want all of these writes to either succeed together or all fail.  The theory goes that you don’t want to get the first 2 lines of the order saved, but then error trying to write line #3 and fail to update the customer or product.  You want to be confident that all these steps will succeed or fail.

A typical method that uses the Unit of Work Pattern would look like so:

public int SaveOrder(int CustomerId, List<OrderDetail> OrderLines) {



    MyDataContext db = new MyDataContext();

   

    Customer c = db.Customers.First( c => c.ID == CustomerId );



    Order o = new Order {

        OrderDate = DateTime.Now,

        CustomerId = CustomerId,

    };



    c.LastOrderDate = o.OrderDate;



    db.Orders.Insert( o );

    db.OrderDetails.InsertRange( OrderLines );

   

    db.SaveChanges();



    return o.ID;

}

You can always spot the Unit-of-Work pattern with it’s tell-tale “now go do it” method — in this case named “SaveChanges”.

I could refactor this into 2 or 3 methods, one that creates the order, one that updates the customer, and all the while hang onto that stateful Data connection until I finally complete that work unit.  These methods could call different stored procedures to do each step if need be.  But good, bad, or indifferent, I must keep track of my handle to my work package until I’m done, then I must specifically say “done”.

Why use the Unit-of-Work pattern rather than just running each query separately?  Because I’m confident that the entire work unit will either succeed or fail, I’ll never get caught with an inconsistent data state.

Repository Pattern

The Repository Pattern’s focus is to create an abstraction between the data store and the application so the application doesn’t need to think about how it’s stored, only that this widget stores it.  The Repository is responsible for doing all the wackiness of connecting to the data store, opening the db connection, forming the query parameters, containing the open connection, etc.  A Repository class has methods that take in objects or parameters, and return either an object or a list of objects.  A Repository method doesn’t do business logic outside of simple validation.  It just shims data to the data store.

A typical class that uses the Repository Pattern would look like so:

public class CustomerRepository {



    public Customer GetById( int CustomerId ) {

        using ( MyDataContext db = new MyDataContext() ) {

            return (

                from c in db.Customers

                where c.ID == CustomerId

                select c

            ).FirstOrDefault();

        }

    }



    public void Save( Customer c ) {

        using ( MyDataContext db = new MyDataContext() ) {

            if ( c.ID < 1 ) {

                db.Add( c );

            } else {

                db.Update( c );

            }

            db.SaveChanges(); // Sadly, Microsoft’s ORM is Unit-of-Work

            // so we’re just saying “my unit is this method”.

        }

    }



}


Usage of this class is pretty straight forward:

public void ChangeCustomerName( int CustomerId, string FirstName, string LastName ) {

    CustomerRepository r = new CustomerRepository(); // Since the Repository is stateless,
    // this could be a property on this class rather than a new instance

    Customer c = r.GetById( CustomerId );

    c.FirstName = FirstName;

    c.LastName = LastName;

    r.Save( c );

}

Notice that the consuming class doesn’t need to know if GetById() was a stored procedure, or used an XML file or called an external service.  It just asked for something, passing in simple parameters, and got back a result.

Why use the Repository Pattern rather than just create an instance of the DataContext everywhere and just query stuff?  Here’s a few reasons:

1. We can easily evaluate data usage, and optimize queries and indexes, because all queries are very carefully defined in a specific section of the code.

2. Data connections are opened and closed within the method, so no connections leak. (Yes, .net’s connection pooling insures we’re not actually hammering the db.)

3. If we ever need to swap data access strategies (LinqToSql to Entity Framework for example), we likely replace the DataContext class, change the Repository methods to call the new Context’s methods, but nothing else in the app needs to change.  OK, if your Data Access strategy requires your objects derive from something, you’ll need to adjust that too.  But the beauty of things like Entity Framework Code First or NHibernate or Dapper is that your entity classes don’t need to derive from anything funky — they’re just plain old C# objects.

A composite Unit-of-Work and Repository Pattern

Well we’ve painted a nice picture of each of the patterns and their benefits, but what if I want the best of both worlds?  What if I want to know everything in various tables and methods happens at once but I want that clean separation that the Repository gives me?  That turns out to be a pretty simple adjustment, though often it’s overkill for the task at hand.  But most of the “Repository Pattern” samples from Microsoft will actually do it this way.

Here’s an example of the hybrid Unit-of-Work / Repository Pattern:

public class BaseRepository {



    public class UnitOfWorkHandle {

        internal MyDataContext db { get; set; }

    }



    public UnitOfWorkHandle StartUnitOfWork() {

        return new UnitOfWorkHandle {

            db = new MyDataContext();

        };

    }



    public void FinishUnitOfWork() {

        db.SaveChanges();

    }



}



public class CustomerRepository : BaseRepository {



    public Customer GetById( UnitOfWorkHandle Handle, int CustomerId ) {

        return (

            from c in Handle.db.Customers

            where c.ID == CustomerId

            select c

        ).FirstOrDefault();

    }



    public void Save( UnitOfWorkHandle Handle, Customer c ) {

        if ( c.ID < 1 ) {

            Handle.db.Add( c );

        } else {

            Handle.db.Update( c );

        }

    }



}


This is pretty cool:

1. The actual implementation details of my data access strategy is hidden (and thus easily replaceable)

2. All the queries are clearly defined and easily auditable

3. I’m confident that either everything will succeed or everything will fail

It has some draw-backs though:

1. Usage is pretty complex:

public void ChangeCustomerName( int CustomerId, string FirstName, string LastName ) {

    CustomerRepository r = new CustomerRepository();

    UnitOfWorkHandle h = r.StartUnitOfWork();

    Customer c = r.GetById( h, CustomerId );

    c.FirstName = FirstName;

    c.LastName = LastName;

    r.Save( h, c );

    r.FinishUnitOfWork();

}

2. If I forget to call FinishUnitOfWork() absolutely nothing happens: no error, no warning, no data is saved, it just goes poof, and sadly, it’s very easy to do.

Which to Use?

Ultimately the choice of which Data Access Pattern you use (similarly to your decision of which ORM / data transport technology you use) depends on the situation.  Do you want clean separation of concerns between your tiers?  Do you need to know that everything is executed together?  Would you rather a simpler interface to getting data?  Some even argue that Microsoft’s ORM tools are themselves the “Data Layer”, and that any pattern that wraps it is wasteful.  Choose the strategy that gives you the best value for the needs of the project: speed of development, maintainable code, legible code, data access speed, etc.

Rob

Demystifying Lambdas in C# 3.0

I’ve had this conversation a few times, so it seems natural that it’d evolve onto my blog in time.  The conversation typically goes like this: “There’s this weird thing I don’t get.  It looks like this: x => x < 6 and like this: Func<int,bool> p.”  Why are these so magical?  How did they come to be?  That’s what we’ll look at here.

Let’s start by clearly defining Lambda.  It’s a function pointer (for the C/C++ among us), or it’s a short-hand way to define a method (for those of us without that much hair loss), and it grew out of C#’s delegates.  They just make it simpler to pass basic (and not so basic) logic to another procedure.

In .NET 1.0, we had delegates.  MSDN defines them as “a type that references a method” or put more simply “a function pointer”.  Somewhere in my class definition, I’d create the delegate definition:

public delegate bool LessThanSixDelegate( int InputVar );

Elsewhere in the class, I’d create the implementation method definition:

public bool MethodName( int InputVar ) {

    return InputVar < 6;

}

Then embedded in some method somewhere I would instantiate this delegate, referencing the MethodName() function:

LessThanSixDelegate methodPointerInstance = new LessThanSixDelegate( MethodName );

Then I’d use the instance like so:

methodPointerInstance( 12 );

That’s .NET 1.0 code, and it’s well worn, and quite verbose.

Fast-forward a few years, and we’re at .NET 2.0, and the latest hotness is “Anonymous Methods” — basically delegates without all the pomp and circumstance:

public delegate bool LessThanSixDelegate( int InputVar );

LessThanSixDelegate methodPointerInstance = delegate( int InputVar ) { return InputVar < 6; };

We’re making great progress.  I still need the delegate definition, but I don’t need to separate the method that does the work from the instance of the delegate.  I create an inline method — an anonymous method — because the method doesn’t have a name, only the instance has a name.

Fast-forward to .NET 3.0, and we now have Lambdas.  The main goal is to get more terse, avoid redundant characters, and get rid of the delegate definition.  Now we can create the delegate definition and method implementation all at once as we instantiate the instance.

var methodPointerInstance = ( int InputVar ) => { return InputVar < 6; };

They needed a character to denote the difference between input parameters and method body, and to denote it as a quick-built delegate — function pointer — lambda.  The character of choice: “=>“, pronounced “such that”.  My method is basically “take in an int InputVar, and calculate InputVar such that InputVar is less than 6.”

This is gorgeous, but there’s still some redundancy.

If the usage determines the input parameter’s type, we don’t need to specify it.  Let’s simplify by removing it:

var methodPointerInstance = ( InputVar ) => { return InputVar < 6; };

If we have only one line in our method, we don’t need the return or the curly braces.  Let’s simplify it to just this:

var methodPointerInstance = ( InputVar ) => InputVar < 6;

If we only have one input parameter, we can avoid the parens around it and we’re left with this:

var methodPointerInstance = InputVar => InputVar < 6;

If I want to name my input parameter “x” instead of “InputVar”, I could yield this:

var methodPointerInstance = x => x < 6;

Gorgeously tiny, very sweet.

Well, all these simplifications were completely optional.  These two lines are completely identical:

var methodPointerInstance = ( int InputVar ) => { return InputVar < 6; };
var methodPointerInstance = x => x < 6;

I can also choose which of these simplifications I prefer, and leverage that syntax.

Well, what if the assumptions we made while simplifying it don’t hold true?  What if we have zero parameters?  Or we have more than one parameter?  Well, we can’t leave off the parens then.  What if we have more than one line in our function?  Then we can’t leave off the curly braces or return line.  Here’s an example of each:

Zero parameters:

var methodPointerInstance = () => 5 < 6;

Two parameters:

var methodPointerInstance = ( Param1, Param2 ) => Param1 < Param2;

Two line long method body:

var methodPointerInstance = InputVar => {
    int comparer = 6;
    bool result = InputVar < comparer;
    return result;
};

I could also choose to add back in any of the short-cut things that I had removed.  Definitely season to taste.  All else being equal though, I like typing less.

So what of this construct: Func<int,bool>?  That’s just a short-cut way of generically specifying a delegate as a parameter into a method.  Action<T,U,V> is that way too.  Func<> will always return the last parameter and take in all the rest as input parameters.  Action<> will always take in all the parameters and return type is void.  Let’s see each in action:

Func<int,bool> methodPointerInstance = InputVar => InputVar < 6;

This “anonymous method pointer” takes in a single int, and returns a bool.

Func<int,int,bool> methodPointerInstance = (Param1,Param2) => Param1 < Param2;

This func takes in two int parameters and returns a bool.

Action<int,bool> methodPointerInstance = (Param1,Param2) => {

    if ( Param2 ) {

        DoIt(Param1);

    }

};

This action takes in two parameters and returns nothing.

So, now when the method signature intelisense pops up with Func<int,bool> methodSignature, no need to run for the hills.  Just pass in x => x < 6 — a lambda that matches the delegate definition using this cool short-cut syntax.

Lambdas are immensely powerful, and your existing skills in forming delegates to satisfy click event handlers already gives you the skills you need to leverage them.  At the end of the day, they’re just function pointers.  Awesome.

Rob

Configuring other IIS boxes in the web farm

Configuring the first IIS 7.x box is far easier than IIS 6 was, but configuring multiple web servers to behave identically can be a pain.  Web Farm Framework (available in Web Platform Installer) can automatically synchronize things, but these settings change so rarely, and changes need to propagate immediately that I’d rather do this manually.  Well, constructing the 3rd or 4th or nth machine gets old.  Can we make this easier?  Most definitely we can.

Back in the IIS 6 days, the “IIS Metabase” was a scary thing — like modifying the registry or getting surgery.  Granted, we did this every day, but it was always daunting.  In IIS 7, the entirety of the IIS configuration details are in xml in C:WindowsSystem32inetsrvconfigapplicationHost.config (unless they’re overridden in each site’s web.config).  How do you set up machine 2 to behave exactly as machine 1?  You diff the files and copy nodes.  Yeah, no more surgery.  Awesome.

Ok, setting up IIS #2 isn’t quite as simple as diffing the files, but it’s pretty close.  Here’s a rough checklist of things I do to make machine 2 function identically to machine 1:

1. Install IIS on each machine
2. Install any plugins / extensions on each machine – typically this is merely a trip through Web Platform Installer
3. Configure Machine 1 to be perfect
4. Backup C:WindowsSystem32inetsrvconfigapplicationHost.config on both machines — it’s easy to mess up, and running without a safety net is bad
5. Diff C:WindowsSystem32inetsrvconfigapplicationHost.config between the two machines, and begin noticing the differences
6. Copy changes from machine 1 to machine 2
7. Restart IIS or reboot (you probably haven’t rebooted since installing Windows Updates) — probably not essential, but best not to get started on the wrong foot

As we’re diffing applicationHost.config we’ll see a few things that we can merge, and a few things that must stay different.  Let’s look through a few sections:

<configProtectedData> node has AesProvider and IISWASOnlyAesProvider nodes.  These include machine-specific details.  If you accidentally merge these details between the two machines, go to your backup and get the original details back.  I’ve never personally hosed a box by doing so, but I’ve also treaded very carefully here.

<system.applicationHost><applicationPools> node includes one node per app pool.  Do you always set them to 4.0, startMode=”AlwaysRunning” or anything else interesting?  It isn’t 3 or 5 clicks away, it’s just a text file change now.  Be careful not to merge an identity password though — it’s machine-specifically encrypted.  Just merge in all the app pools from Machine 1 into place.

<system.applicationHost><sites> node includes one child <site> node per website.  You can configure everything here just by adding attributes and child nodes.  Or add a complete site by merging in another <site> node.  (Be careful to insure their id=”” are unique and that they reference an applicationPool that exists.)  Just merge in all the sites from Machine 1 into place.

<system.webServer><globalModules> includes a list of all the httpModules installed into IIS.  Depending on what order you clicked the check-boxes while installing IIS or what order Web Platform Installer installed plugins, these may be in different orders between the machine.  Provided you don’t add or remove nodes, you can reorder them for “cleanliness”.

<location path=”…”> nodes at the bottom alter authentication protocols for each site.  You can do similar overloads in web.config, but if you configured it through IIS, they’ll be here.  (Alternatively, if you configured it in Visual Studio, the details may only be in that site’s web.config.)

Do you have any other noteworthy nodes in your IIS applicationHost.config files?  Any other techniques for configuring IIS with ease?

Enjoy!

Rob