<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>I am a husband, software developer, avid cyclist, and soon-to-be triathlete living in Indianapolis, Indiana.</description><title>Caffeine-Powered Life</title><generator>Tumblr (3.0; @jarrettmeyer)</generator><link>http://jarrettmeyer.com/</link><item><title>I Love PowerShell / I Hate PowerShell</title><description>&lt;p&gt;Here’s a wonderful little tool called &lt;a href="https://help.ubuntu.com/community/grep" target="_blank"&gt;grep&lt;/a&gt; in Linux. It’s crazy easy to use.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;% grep 'search string' filename&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And here’s an example:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;% grep 'Html.ActionLink' *.cshtml&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And it works exactly the way you would expect it to work. Run this from the root of an MVC project, and you’ll find all of the links in your application.&lt;/p&gt;
&lt;p&gt;Here’s the equivalent line in PowerShell.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&gt; Get-ChildItem .\* -include *.cshtml -recurse | Select-String -pattern "Html.ActionLink"&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I love that we have a solid scripting option available in Windows now. I love that we can really build some great stuff with PowerShell. But really, are there any PS development authors out there who actually use this stuff in a real work environment? I suppose it’s not really so different from the rest of the Microsoft story.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/16767682953</link><guid>http://jarrettmeyer.com/post/16767682953</guid><pubDate>Mon, 30 Jan 2012 13:09:42 -0500</pubDate></item><item><title>What Was I Thinking?</title><description>&lt;p&gt;Although I was quite tired from laying tile on Saturday and Sunday, I got up and went to the gym this morning. I swam 1000m – the furthest I have swam in a long, long time.&lt;/p&gt;
&lt;p&gt;I am exhausted. What was I thinking when I signed up for a &lt;a href="http://ironmanmuncie.com/" target="_blank"&gt;Half Ironman&lt;/a&gt;? I’ll be required to swim 1,931 meters for the first leg of my race. July 7, 2012 is not so far away. Only 179 days to go. Ack!&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/15562680234</link><guid>http://jarrettmeyer.com/post/15562680234</guid><pubDate>Mon, 09 Jan 2012 06:21:50 -0500</pubDate></item><item><title>Oh, The Places You'll Go</title><description>&lt;p&gt;Here it is, the complete list of everything I’ve read in 2011. Meaghan got me a Kindle for our anniversary this year, and just started devouring fiction, a few biographies, and just about anything else that interested me. I don’t think I’ve ever read that much in my life as what I read this past year.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Watership-Down-Novel-Richard-Adams/dp/0743277708/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339477&amp;sr=1-1" target="_blank"&gt;Watership Down&lt;/a&gt; by Richard Adams 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Dogs-Purpose-W-Bruce-Cameron/dp/0765330342/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339868&amp;sr=1-1" target="_blank"&gt;A Dog’s Purpose&lt;/a&gt; by W. Bruce Cameron 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Enders-Game-Ender-Book-1/dp/0812550706/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339838&amp;sr=1-1" target="_blank"&gt;Ender’s Game&lt;/a&gt; by Orson Scott Card 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Room-Novel-Emma-Donoghue/dp/0316098329/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324340087&amp;sr=1-1" target="_blank"&gt;Room&lt;/a&gt; by Emma Donaghue 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Ruby-Programming-Language-David-Flanagan/dp/0596516177/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339394&amp;sr=1-1" target="_blank"&gt;The Ruby Programming Language&lt;/a&gt; by David Flanagan and Yukihiro Matsumoto 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339365&amp;sr=1-1" target="_blank"&gt;Growing Object-Oriented Software, Guided by Tests&lt;/a&gt; by Steve Freeman and Nat Pryce 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Making-Supper-Safe-Quest-Safety/dp/1605293091" target="_blank"&gt;Making Supper Safe&lt;/a&gt; by Ben Hewitt
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Long-Run-Firefighters-Triumphant-Comeback/dp/B005CDTJ48/ref=sr_1_2?s=books&amp;ie=UTF8&amp;qid=1324339732&amp;sr=1-2" target="_blank"&gt;The Long Run&lt;/a&gt; by Matt Long 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Game-Thrones-Song-Fire-ebook/dp/B000QCS8TW/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339602&amp;sr=1-1" target="_blank"&gt;A Game of Thrones: A Song of Ice and Fire Book 1&lt;/a&gt; by George R. R. Martin 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Clash-Kings-Song-Fire-Book/dp/0553381695/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339550&amp;sr=1-1" target="_blank"&gt;A Clash of Kings: A Song of Ice and Fire Book 2&lt;/a&gt; by George R. R. Martin 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Ghost-Wires-Adventures-Worlds-Wanted/dp/0316037702/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339967&amp;sr=1-1" target="_blank"&gt;Ghost in the Wires: My Adventures as the World’s Most Wanted Hacker&lt;/a&gt; by Kevin Mitnick 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Home-Vinyl-Cafe-Stuart-McLean/dp/B001G8WREW/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324340040&amp;sr=1-1" target="_blank"&gt;Home from the Vinyl Café&lt;/a&gt; by Stuart McLean 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Homeland-Trilogy-Forgotten-Realms-Legend/dp/0786939532/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339655&amp;sr=1-1" target="_blank"&gt;Homeland: The Dark Elf Trilogy, Part 1&lt;/a&gt; by R. A. Salvatore 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Exile-Forgotten-Realms-Legend-Drizzt/dp/0786939834/ref=sr_1_3?s=books&amp;ie=UTF8&amp;qid=1324339919&amp;sr=1-3" target="_blank"&gt;Exile: Part 2&lt;/a&gt; by R. A. Salvatore 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Need-Talk-About-Kevin-ebook/dp/B004ZY0VHY/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324340154&amp;sr=1-1" target="_blank"&gt;We Need to Talk About Kevin&lt;/a&gt; by Lionel Shriver 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/C-Depth-Second-Jon-Skeet/dp/1935182471/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339415&amp;sr=1-1" target="_blank"&gt;C# In Depth, 2nd Edition&lt;/a&gt; by Jon Skeet 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Immortal-Life-Henrietta-Lacks/dp/1400052181/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339794&amp;sr=1-1" target="_blank"&gt;The Immortal Life of Henrietta Lacks&lt;/a&gt; by Rebecca Skloot 
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/Help-Deluxe-Kathryn-Stockett/dp/0399157913/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1324339715&amp;sr=1-1" target="_blank"&gt;The Help&lt;/a&gt; by Kathryn Stockett&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I thought it would be cool to make this list, but I really didn’t know it would be that lengthy. I would have never guessed that I had read 18 books in 2011. Bring it on, 2012!&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/15187379153</link><guid>http://jarrettmeyer.com/post/15187379153</guid><pubDate>Mon, 02 Jan 2012 11:52:00 -0500</pubDate></item><item><title>Fuck You, Printer</title><description>&lt;p&gt;I don’t care if you’re out of color ink. I just want to print a black and white document!&lt;/p&gt;
&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/12/fuck_you_printer.png"/&gt;&lt;/p&gt;
&lt;p&gt;And it’s not even good grammar.&lt;/p&gt;
&lt;p&gt;&lt;sigh/&gt;&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/14623704481</link><guid>http://jarrettmeyer.com/post/14623704481</guid><pubDate>Thu, 22 Dec 2011 12:59:09 -0500</pubDate></item><item><title>My Winter Project</title><description>&lt;p&gt;Between Christmas and New Year’s, I plan to start learning Windows &lt;a href="http://technet.microsoft.com/en-us/library/bb978526.aspx" target="_blank"&gt;PowerShell&lt;/a&gt;. I love my command line, so getting a more powerful command line seems like an ideal thing for me. I usually write little Ruby scripts for the little one-off things that I need to do that a just a little more complicated than a *.bat file. It would be nice to have a native Windows option when it comes to this type of thing. That’s where PowerShell comes in.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/14508901288</link><guid>http://jarrettmeyer.com/post/14508901288</guid><pubDate>Tue, 20 Dec 2011 08:56:38 -0500</pubDate></item><item><title>Getting Raw (and Copying Rails)</title><description>&lt;p&gt;Ever run into problems where you really want to see exactly what the user submitted to your web application? I do, especially when I lack a one-to-one relationship between the view and model. This seems like something an action filter should be able to do for me. And as you might have gathered from the title, logging posted form values is something that Rails does out of the box.&lt;/p&gt;
&lt;p&gt;There’s a security concern here that we need to concern ourselves with. We’re usually smart enough to encrypt passwords, credit card numbers, and other sensitive information in our databases. &lt;em&gt;And if you’re not encrypting that stuff, you really should be. Like now.&lt;/em&gt; We don’t want to introduce a new security hole in our application by logging that information in our database in our logging table. Who cares if your user table is protected if I can just strip the passwords from your log history. This is, obviously, not ideal.&lt;/p&gt;&lt;pre&gt;public class LogRequestFormAttribute : ActionFilterAttribute
{
    private static readonly string[] defaultProtectedFields = new[] { "CreditCard", "CreditCardNumber", "NewPassword", "NewPasswordConfirmation", "Password", "PasswordConfirmation" };
    private static string[] protectedFields;

    static LogRequestFormAttribute()
    {
        Bus.Instance.AddMessageHandlerType(typeof(DebugLogRequestFormMessageObserver));
    }

    public static IEnumerable&lt;string&gt; ProtectedFormFields
    {
        get { return protectedFields ?? (protectedFields = ConfigProtectedFormFields.Union(defaultProtectedFields).Distinct().ToArray()); }
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Bus.Instance.Send(new LogRequestFormMessage(filterContext));
    }

    private static IEnumerable&lt;string&gt; ConfigProtectedFormFields
    {
        get
        {
            string protectedFormFieldsString = ConfigurationManager.AppSettings["ProtectedFormFields"];
            if (string.IsNullOrEmpty(protectedFormFieldsString)) return new string[] { };
            var protectedFormFields = protectedFormFieldsString
                .Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
                .Select(s =&gt; s.Trim());
            return protectedFormFields;
       }
   }
}
&lt;/pre&gt;
&lt;p&gt;Right off the bat, I am making sure that form fields called CreditCard, CreditCardNumber, NewPassword, NewPasswordConfirmation, Password, or PasswordConfirmation are listed as protected. Seriously, I don’t care what what your configuration says.&lt;/p&gt;
&lt;p&gt;Obviously, this is something Microsoft would &lt;strong&gt;never&lt;/strong&gt; do. Microsoft builds a framework. If you want to use that framework in a hazardous and potential unsecure way, then that’s your problem. Me? I’m not bound by the same constraints.&lt;/p&gt;
&lt;p&gt;I do recognize that you may have other values that you want kept out of your logs. Have no fear: it’s easy enough to configure as part of your &lt;code&gt;web.config&lt;/code&gt; file.&lt;/p&gt;&lt;pre&gt;&lt;add key="ProtectedFormFields" value="CCNumber"  /&gt;&lt;/pre&gt;
&lt;p&gt;And with that, we’re now ensuring that anytime a form is posted, any field name CCNumber will be obscured in the message. The trick is in the message. (Don’t worry, it’s not much of a trick.)&lt;/p&gt;&lt;pre&gt;public override string ToString()
{
    var sb = new StringBuilder();
    sb.AppendLine(string.Format("Url: {0}, Controller: {1}, Action: {2}", Url, ControllerName, ActionName));
    var keyStrings = new List&lt;string&gt;();
    foreach (string key in FormData.AllKeys)
    {
        var value = GetFormValue(key);
        var keyString = string.Format("{0}: {1}", key, value);
        keyStrings.Add(keyString);
    }
    sb.AppendLine(string.Join(", ", keyStrings));
    return sb.ToString();
}

internal string GetFormValue(string key)
{
    string value;
    if (IsProtected(key))
    {
         var valueLength = (FormData[key] ?? "").Length;
         value = new string('*', valueLength);                
    }
    else
    {
        value = FormData[key] ?? "";
    }            
    return value;                        
}
&lt;/string&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;What’s Up With The Bus?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The bus is a super simple in-memory message bus infrastructure to send events. It’s part of the Curiosity.Common library. Feel free to check it out!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The DebugLogRequestFormMessageObserver&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The debug observer will write to the Visual Studio debug output window. You’ll get something like this.&lt;/p&gt;&lt;pre&gt;Url: /home/testform, Controller: home, Action: testform
FirstName: Jarrett, LastName: Meyer, Password: **************, PasswordConfirmation: **************, SSN: ***********
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Adding Your Own Handler&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Want to use log4net? It’s easy enough to add your own message handler.&lt;/p&gt;&lt;pre&gt;public class Log4NetLogRequestFormMessageObserver : MessageHandlerBase&lt;logrequestformmessage&gt;
{
    private readonly ILog log = LogManager.GetLogger("form-logger");

    public override void Handle(LogRequestFormMessage message)
    {
        log.Debug(message);
    }
}&lt;/logrequestformmessage&gt;&lt;/pre&gt;
&lt;p&gt;Simple!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now With More NuGet Awesome&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This awesome new feature has been added to &lt;a href="https://github.com/jarrettmeyer/curiosity-common-mvc" target="_blank"&gt;Curiosity.Common.Mvc&lt;/a&gt; (version 1.8), and is available on &lt;a href="http://nuget.org/packages/Curiosity.Common.Mvc" target="_blank"&gt;NuGet&lt;/a&gt;. For more info, check out the &lt;a href="https://github.com/jarrettmeyer/curiosity-common-mvc/wiki/Request-Form-Logging" target="_blank"&gt;wiki page on GitHub&lt;/a&gt;.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/14356554059</link><guid>http://jarrettmeyer.com/post/14356554059</guid><pubDate>Sat, 17 Dec 2011 10:59:08 -0500</pubDate><category>asp.net mvc</category><category>csharp</category><category>code</category></item><item><title>Accessing Application State Information</title><description>&lt;p&gt;In every application I’ve every written, I’ve had to deal with state values in some way. At the simplest level, you’ll usually need to know the answer to three questions.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Is there currently an authenticated user? 
&lt;/li&gt;&lt;li&gt;Who is the current user? 
&lt;/li&gt;&lt;li&gt;What is the current user allowed to do?&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Just about every web application needs to solve these three problems. In fact, this very question was posed by a comment from my &lt;a href="http://jarrettmeyer.com/post/14173467783/easy-audit-information-in-entity-framework" target="_blank"&gt;previous post&lt;/a&gt;. In the commenter’s example, he has a separation of layers that will not allow him to access things like HTTP context or session from his data tier library. (There’s no reference to System.Web from the data tier.)&lt;/p&gt;
&lt;p&gt;You know what I’m thinking? This sounds like an interface!&lt;/p&gt;&lt;pre&gt;public interface IUserState
{
  bool IsAuthenticated { get; }
  string UserName { get; }
  string[] Roles { get; }
}
&lt;/pre&gt;
&lt;p&gt;This is a bit of a trick in a web environment, because the web is naturally stateless. You can’t use statics the same as you would with a desktop application. You must use a factory, similar to how &lt;code&gt;HttpContext.Current&lt;/code&gt; is resolved.&lt;/p&gt;
&lt;p&gt;I should point out that the concept of a user state is even lower than your data tier.&lt;/p&gt;&lt;pre&gt;public class UserState
{
  private static IUserStateFactory factory;

  public static IUserState Current
  {
    get { return factory.UserState; }
  }

  public static void SetFactory(IUserStateFactory userStateFactory)
  {
    factory = userStateFactory;
  }
}
&lt;/pre&gt;
&lt;p&gt;This part is important: &lt;strong&gt;we cannot store the user state instance in a static field&lt;/strong&gt;. This is one of the biggest sources of problems that I find when working with ASP.NET application. (I’ve seen this all too often in both WebForms and MVC. Remember, the underlying ASP.NET technology is the same.) The static field life cycle is stored within the AppDomain. In an ASP.NET project, this AppDomain is not guaranteed to go to the same user every time. When you have multiple users on a web page. However, we can easily save the factory in a field, since the role of a factory is to create the objects.&lt;/p&gt;
&lt;p&gt;Now, we need some implementations that will work with an HTTP session.&lt;/p&gt;&lt;pre&gt;public class HttpSessionUserState : IUserState
{
  private readonly HttpSessionState session;

  public HttpSessionUserState(HttpSessionState session)
  {
    this.session = session;
  }

  public bool IsAuthenticated
  {
    get { return UserName != null; }
  }

  public string UserName
  {
    get
    {
      object userName = session["UserName"];
      return (userName != null) ? (string)userName : null;
    }
  }

  public string[] Roles
  {
    get
    {
      object roles = session["Roles"];
      return (roles != null) ? (string[])roles : new string[] { };
    }
  }
}
&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Yes, I prefer to return an empty array of roles, rather than null, in this case.&lt;/em&gt; The way .NET deals with nulls is a constant source of frustration, and I hate seeing &lt;code&gt;NullReferenceException&lt;/code&gt;’s sprinkled through the error logs.&lt;/p&gt;
&lt;p&gt;We also need an implementation of the factory.&lt;/p&gt;&lt;pre&gt;public class HttpSessionUserStateFactory : IUserStateFactory
{
  public IUserState UserState
  {
    get
    {
      var session = HttpContext.Current.Session;
      return new HttpSessionUserState(session);                
    }
  }
}
&lt;/pre&gt;
&lt;p&gt;To round out this example we need to register the factory with the static class. This should be done as part of your application startup. In a web app, that means you should put this in your Global.asax file. Create a method like this, and add a call to this method to your Application_Start.&lt;/p&gt;&lt;pre&gt;private void RegisterUserStateFactory()
{
  var userStateFactory = new HttpSessionUserStateFactory();
  UserState.SetFactory(userStateFactory);
}&lt;/pre&gt;
&lt;p&gt;This is a little lengthy. We’re looking at 5 total classes, but all of the classes are quite small. The first three classes are in a base layer. The specific implementations are in your are part of your startup layer. This works because we are depending on an interface, not a specific implementation. Unit testing is quite easy as well. We can create InMemoryUserState and InMemoryUserStateFactories quite easily, or we can just mock out their implementations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Back to my previous post&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Updating modified entries now needs to look something like this.&lt;/p&gt;&lt;pre&gt;private void UpdateModifiedEntries()
{
  var modifiedEntries = ChangeTrackerEntries.Where(e =&gt; e.State == EntityState.Modified &amp;&amp; e.Entity is IAuditable).Select(e =&gt; e.Entity);
  foreach (var modifiedEntry in modifiedEntries)
  {
    modifiedEntry.UpdatedAt = DateTime.UtcNow;
    modifiedEntry.UpdatedBy = UserState.Current.UserName; // used to be HttpContext.Current.UserName
  }
}
&lt;/pre&gt;
&lt;p&gt;Happy to help!&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/14217009453</link><guid>http://jarrettmeyer.com/post/14217009453</guid><pubDate>Wed, 14 Dec 2011 10:49:12 -0500</pubDate></item><item><title>Easy Audit Information in Entity Framework</title><description>&lt;p&gt;Another pretty common problem – we have a lot of tables that have the same 4 columns to track simple audit information. I’m sure you’ve all seend something like this before.&lt;/p&gt;&lt;pre&gt;  CreatedAt    DATETIME NULL,
  CreatedBy    VARCHAR(256) NULL,
  UpdatedAt    DATETIME NULL,
  UpdatedBy    VARCHAR(256) NULL
&lt;/pre&gt;
&lt;p&gt;When inserting or updating records, we really don’t want to mess around with updating all of this stuff all of the time, especially if you have a lot of models in your application. It’s just a pain, and it violates &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself" target="_blank"&gt;DRY&lt;/a&gt;. So let’s fix that.&lt;/p&gt;
&lt;p&gt;The first thing we need is an interface. We’ll implement this interface on all of our models that have this audit tracking information.&lt;/p&gt;&lt;pre&gt;public interface IAuditable
{
  DateTime? CreatedAt { get; set; }
  string CreatedBy { get; set; }
  DateTime? UpdatedAt { get; set; }
  string UpdatedBy { get; set; }
}
&lt;/pre&gt;
&lt;p&gt;Now we need to look to our &lt;code&gt;DbContext&lt;/code&gt; for further insights. (I’m using the &lt;code&gt;DbContext&lt;/code&gt; code generator, available as a Visual Studio Extension.) We see that our entity context extends the &lt;code&gt;DbContext&lt;/code&gt;, and it’s created as a partial class by default. Let’s take advantage of this and override the &lt;code&gt;SaveChanges&lt;/code&gt; method.&lt;/p&gt;&lt;pre&gt;partial class MyContext
{
  public override int SaveChanges()
  {
    UpdateAuditInformation();
    return base.SaveChanges();
  }

  private IEnumerable&lt;dbentityentry&gt; ChangeTrackerEntries
  {
    get { return this.ChangeTracker.Entries(); }
  }

  private void UpdateAuditInformation()
  {
    UpdatedAddedEntries();
    UpdatedModifiedEntries();
  }

  private void UpdateAddedEntries()
  {
    var addedEntries = ChangeTrackerEntries.Where(e =&gt; e.State == EntityState.Added &amp;&amp; e.Entity is IAuditable).Select(e =&gt; e.Entity);
    foreach (var addedEntry in modifiedEntries)    
    {
      addedEntry.CreatedAt = DateTime.UtcNow;
      addedEntry.CreatedBy = HttpSession.Current.UserName;
      addedEntry.UpdatedAt = addedEntry.CreatedAt;
      addedEntry.UpdatedBy = addedEntry.CreatedBy;
    }
  } 

  private void UpdateModifiedEntries()
  {
    var modifiedEntries = ChangeTrackerEntries.Where(e =&gt; e.State == EntityState.Modified &amp;&amp; e.Entity is IAuditable).Select(e =&gt; e.Entity);
    foreach (var modifiedEntry in modifiedEntries)
    {
      modifiedEntry.UpdatedAt = DateTime.UtcNow;
      modifiedEntry.UpdatedBy = HttpSession.Current.UserName;
    }
  }
}
&lt;/dbentityentry&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;HttpSession.Current&lt;/code&gt; is just a strongly typed wrapper for an HTTP session, specific to this application. There’s nothing special, so feel free to use any method available to get the current application user. For example, if you’re using FormsAuthentication or WindowsAuthentication, you can simply call HttpContext.Current.User.&lt;/p&gt;
&lt;p&gt;Hope you like it!&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/14173467783</link><guid>http://jarrettmeyer.com/post/14173467783</guid><pubDate>Tue, 13 Dec 2011 13:32:00 -0500</pubDate><category>code</category><category>csharp</category><category>entity framework</category></item><item><title>The Horror Of The Code Sample</title><description>&lt;p&gt;I have written before that I have to &lt;a href="http://jarrettmeyer.com/post/8776179656/all-about-the-interview"&gt;interview incoming developer candidates&lt;/a&gt;. It is &lt;strong&gt;not&lt;/strong&gt; my favorite part of my job. Sure, I love geeking out with other developers, but that happens so rarely. It’s embarrassing, really. I didn’t make this up on my own. There’s plenty of &lt;a href="http://ayende.com/blog/102402/negative-hiring-decisions-part-ii"&gt;other people&lt;/a&gt; out there who do this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why A Code Sample?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Because just having one tells us a lot about you. No, we do not expect you to go home and spend 6 – 8 hours programming. But do you do anything at all outside of work? Do you ever contribute to open source projects? Did you ever write a little program to &lt;a href="http://rubyonrails.org/screencasts"&gt;teach yourself something new&lt;/a&gt;? Me? I’m a geek. (We’ve clearly established this.) I maintain my own public &amp; shared &lt;a href="https://nuget.org/packages/Curiosity.Common"&gt;NuGet&lt;/a&gt; repositories, and my code is freely available on &lt;a href="https://github.com/jarrettmeyer"&gt;GitHub&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;But that’s not for everyone. That’s OK; do what you do. But &lt;strong&gt;do something!&lt;/strong&gt; This is partly what Stephen Covey would call &lt;em&gt;&lt;a href="https://www.stephencovey.com/7habits/7habits-habit7.php" target="_blank"&gt;Sharpening the Saw&lt;/a&gt;&lt;/em&gt;. What do you do to keep your skills fresh and up-to-date? How do you learn? What are you working on? If you want to succeed in today’s development world, you need to be tinkering. With something. Anything. And while you’re at it, check your code into a public code repository. I doesn’t even cost anything to share your ideas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What Are The Rules?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;They’re fairly straightforward. Send us something you’ve done that demonstrates your ability as a software developer. It can be big or little, just make sure that you have permission to send it. It should not be proprietary software that belongs to a previous employer. It’s probably not&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What Are We Looking For In A Code Sample?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Honestly, not much. It can be anything. If it’s a language I can read, I’ll take it. Sure, I’d prefer it to be in C#.NET, since that’s what we’re hiring you to do, but I’ll accept Python, Ruby, VB, JavaScript, etc. For what it’s worth, I’d even accept MatLab.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Isn’t This Supposed To Be A Horror Story?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yes. Yes, it is.&lt;/p&gt;
&lt;p&gt;Some people have outstanding resumes and absolutely no code sample at all. It happens, and we might still interview you. In fact, if you can talk the talk well enough, you might not even need a code sample. That, in fact, is a better option than sending us an absolutely terrible code sample. I got to see one today: 1 class, 4 methods (Create, Fetch, Update, List All), 19 pages when printed. No concept of DRY. Validating each property in sequence with a lovely series of if statements. And, of course, they’re all copy/paste duplicated for create and update options. Just absolutely horrible, monstrous code.&lt;/p&gt;
&lt;p&gt;Or, this is the email I sent my boss this morning.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you compare nothing to nothing, there’s not much there to work with. This, however, is the difference between going on a blind date and knowing up front that the other person is ugly.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Don’t get me wrong. I will freely admit to having had written programs that look like that. You know, back before I knew what I was doing. Before I had a clue about LoB software development.&lt;/p&gt;
&lt;p&gt;Despite my complaints, I must interview the candidate anyway, and this does not make me happy.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/14126507236</link><guid>http://jarrettmeyer.com/post/14126507236</guid><pubDate>Mon, 12 Dec 2011 14:42:53 -0500</pubDate></item><item><title>Why Delegates?</title><description>&lt;p&gt;The more code I write, the more I find myself using delegates. Take this part of our &lt;a href="https://github.com/jarrettmeyer/curiosity-common-mvc"&gt;Curiosity.Common.Mvc&lt;/a&gt; library, just added today. Behold, the power of delayed execution.&lt;/p&gt;&lt;pre&gt;return new FormHandlerResult&lt;Logon&gt;(form, () =&gt; RedirectToAction("Index", "Home"), () =&gt; View(form))&lt;br/&gt;           {&lt;br/&gt;               SuccessNotification = () =&gt; "Welcome, " + Session["display_name"]&lt;br/&gt;           }&lt;/pre&gt;
&lt;p&gt;I have a dynamic success notification in this case. The form handler will update the session with the display name, but it’s not set yet. If I were to just use a string for success notification, I couldn’t set the string at a later time. In this case, using a Func&lt;string&gt; solves all of my problems.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/13464583564</link><guid>http://jarrettmeyer.com/post/13464583564</guid><pubDate>Mon, 28 Nov 2011 15:40:12 -0500</pubDate></item><item><title>Indianapolis Monumental Half Marathon Race Report</title><description>&lt;p&gt;It’s been a long, long time since I ran a half-marathon. It’s November, and this is my first one this year. But I’ve also learned that I’m capable of much faster times than what I’ve submitted in the past. It’s really just a matter of making your legs go faster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mile 1&lt;/strong&gt; - 9:18. Seems like a fast start. That’s OK. I know I’ll slow down, and I know I have problems pacing myself. Fast is OK.&lt;br/&gt;&lt;strong&gt;Mile 2 &amp; 3&lt;/strong&gt; – 17:40. I never did see the 2nd mile marker. Meaghan did, so there must have been one. Whatever. Still, a fast start. That’s like, 2 miles where I averaged 8:50/mile.&lt;br/&gt;&lt;strong&gt;Mile 4&lt;/strong&gt; - 8:32. This is where I passed Meaghan. She even yelled out to me, “You’re going faster than 9:00/mile.” I knew that; my watch was working. But, damn, I felt really, really good this morning.&lt;br/&gt;&lt;strong&gt;Mile 5&lt;/strong&gt; – 9:23.&lt;br/&gt;&lt;strong&gt;Mile 6&lt;/strong&gt; – 8:46. Obviously, consistency is not my strong suit here. Still, 6 miles at 53:41 would have led to a 10k PR. In fact, &lt;a href="http://imm2011.onlineraceresults.com/individual.php?bib=6029" target="_blank"&gt;let me show you them&lt;/a&gt;. My 10k time was 55:43 – that’s 9:00/mile flat! My best 10k was just a few weeks ago at a 9:17/mile pace. So now I’m thinking that my next 10k needs to be in sub-9/mile.&lt;br/&gt;&lt;strong&gt;Mile 7&lt;/strong&gt; – 9:00. At this point, my mind starts thinking that I can finish in under 2:00.&lt;br/&gt;&lt;strong&gt;Mile 8&lt;/strong&gt; – 9:30. Um, maybe not.&lt;br/&gt;&lt;strong&gt;Mile 9&lt;/strong&gt; – 9:20. Or maybe.&lt;br/&gt;&lt;strong&gt;Mile 10&lt;/strong&gt; – 9:18. OK, this is crazy, and my mind is really flying around now. That’s 3 really consistent miles. We’ve already established that consistency is not my strong suit. I look at my watch. 1:30:51. I needed to run a 5k in 29 minutes. In theory I could do that – better than that even – but I had just ran the greatest 10 miles of my life. My legs were already aching. And that seed is planted: sub-2:00 isn’t going to happen. And once that seed gets in your head, that’s it. You’ve lost the brain game.&lt;br/&gt;&lt;strong&gt;Mile 11&lt;/strong&gt; – 10:21. This is not how you run a 5k in 29:00.&lt;br/&gt;&lt;strong&gt;Mile 12&lt;/strong&gt; – 10:02. Still going the wrong way.&lt;br/&gt;&lt;strong&gt;Mile 13&lt;/strong&gt; – 10:25. Well, shit.&lt;br/&gt;&lt;strong&gt;Mile 13.1&lt;/strong&gt; – 0:59. Total time was 2:02:40 by my watch, 2:02:39 by the timing chip, and 2:04:30 by the clock. The watch/chip time comes out to 9:22 per mile, which is good enough for preferred seeding for &lt;a href="http://www.500festival.com/marathon/" target="_blank"&gt;Indianapolis Mini Marathon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Don’t get me wrong. Getting a PR and beating my goal time of 2:05 by better than 2 minutes is an outstanding result. But I also watched a sub-2 slip through my toes via my brain. I lost that in my head before I ever lost it in my legs.&lt;/p&gt;
&lt;p&gt;I can definitely tell that hanging out with athletes is having an effect on my energy level. It’s Sunday, and I’ve already registered for a full marathon, the &lt;a href="http://illinoismarathon.com/" target="_blank"&gt;Illinois Marathon&lt;/a&gt;, on April 28. I’ve also registered for a half Ironman, &lt;a href="http://ironmanmuncie.com/" target="_blank"&gt;Muncie&lt;/a&gt;, on July 7. I absolutely must figure out the head game thing in the next 6 months, or I’ll never finish either of those events.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/12439823706</link><guid>http://jarrettmeyer.com/post/12439823706</guid><pubDate>Sun, 06 Nov 2011 17:37:32 -0500</pubDate><category>race</category></item><item><title>Child's Play</title><description>&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/11/childsplay_logo.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;I don’t play a lot of video games. That’s not terribly upsetting, since I was never a real hard-core gamer anyway. I like video games, but I’m not really that good at them. I’m more of the &lt;em&gt;turn-on-God-mode-to-see-what-the-end-is-like&lt;/em&gt; type of gamer. No, that’s not for everyone, but it works for me.&lt;/p&gt;
&lt;p&gt;So even though I don’t play them, I do like to read about the games. One of the feeds in my reader is &lt;a href="http://penny-arcade.com/" target="_blank"&gt;Penny Arcade&lt;/a&gt;. Well, imagine my surprise when I read &lt;a href="http://penny-arcade.com/2011/11/02/childs-play-2011" target="_blank"&gt;this&lt;/a&gt; – an article about &lt;a href="http://childsplaycharity.org/" target="_blank"&gt;Child’s Play&lt;/a&gt;. Between 2003 and 2010, Child’s Play has managed to raise $8.9 million. That’s an outstanding contribution from the gaming world.&lt;/p&gt;
&lt;p&gt;But it’s something that makes me happy/sad. These kids are going through terrible illnesses that no one should have to endure. Let’s say this: they’re not buying consoles and games for kids in the Dr.’s office with runny noses. This is big-time illness.&lt;/p&gt;
&lt;p&gt;I encourage you to check out &lt;a href="http://childsplaycharity.org/" target="_blank"&gt;Child’s Play&lt;/a&gt;. Give them a few bucks. Stand in awe of the healing power of Mario Kart.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/12279250029</link><guid>http://jarrettmeyer.com/post/12279250029</guid><pubDate>Thu, 03 Nov 2011 05:37:47 -0400</pubDate></item><item><title>WTF, Wednesday Edition</title><description>&lt;p&gt;
	It’s too early to find crap like this in your inbox.
&lt;/p&gt;
&lt;p&gt;
	&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/11/bad-email-2011-11-02.png" alt="email image"/&gt;&lt;/p&gt;
&lt;p&gt;
	I can forgive the poor grammar. I am familiar with graduate school engineering programs, so I am used to working with people whose first language is not English. My bigger problem is: &lt;strong&gt;who does this?&lt;/strong&gt; I mean, people got problems. Helping people solve those problems has turned into a &lt;a href="http://stackoverflow.com"&gt;decent business for several people&lt;/a&gt;. &lt;a href="http://tekpub.com"&gt;Lots of people&lt;/a&gt;. I’m happy to help people. That’s why I’ve got this blog. And yes, I do respond to emails.
&lt;/p&gt;
&lt;p&gt;
	But this email isn’t that. It doesn’t describe an actual problem. It’s just a few keywords and a garbage question about ‘innerhtml’, ‘mvc 3’, and ‘xml’.
&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/12238202308</link><guid>http://jarrettmeyer.com/post/12238202308</guid><pubDate>Wed, 02 Nov 2011 08:14:00 -0400</pubDate></item><item><title>Common Class Libraries-Now on Github &amp; NuGet</title><description>&lt;p&gt;In January of this year, I finally had enough side business coming in to justify forming my own company. It’s not a &lt;strong&gt;huge&lt;/strong&gt; amount of side business, but enough to warrant forming an LLC and getting separate bank accounts. You know, the important stuff that you do if you at least want to look legitimate.&lt;/p&gt;
&lt;p&gt;So, without further ado, allow &lt;strike&gt;myself to introduce myself&lt;/strike&gt; me to introduce…&lt;/p&gt;
&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/curiositysoftware.com/images/curiosity_logo_400px.png"/&gt;&lt;/p&gt;
&lt;p&gt;No, this is not one of those awesome stories where I come up with something brilliant, sell it, quit my job, and go swimming in my bank vault of gold coins (although I &lt;em&gt;do&lt;/em&gt; love that story). Instead, this is just me, putting myself out there. In this case, “myself” means two class libraries that tend to follow me everywhere I go.&lt;/p&gt;
&lt;p&gt;The two projects can be found on Github &lt;a href="https://github.com/jarrettmeyer/curiosity-common" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="https://github.com/jarrettmeyer/curiosity-common-mvc" target="_blank"&gt;here&lt;/a&gt;. They’ve also been published in NuGet (&lt;a href="http://nuget.org/List/Packages/Curiosity.Common" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://nuget.org/List/Packages/Curiosity.Common.Mvc" target="_blank"&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/10/InstallPackageCuriosityCommon.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/10/InstallPackageCuriosityCommonMvc.png"/&gt;&lt;/p&gt;
&lt;p&gt;So please, take, use, let me know what you like and don’t like. Yes, if you read lots of blogs or use open source, you will probably find some classes/methods that have been wholesale copied from their original authors. If you find something that should have attribution, let me know, and I’ll correct that immediately.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/11986255185</link><guid>http://jarrettmeyer.com/post/11986255185</guid><pubDate>Thu, 27 Oct 2011 05:49:44 -0400</pubDate></item><item><title>Deleting a Folder that You Can’t Delete</title><description>&lt;p&gt;This is a fairly common scenario. I need to delete a folder, but Windows will not let me delete it. I get a nasty message like this.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/10/delete_folder_access_denied.png"/&gt;&lt;/p&gt;

&lt;p&gt;Well isn’t that annoying. Especially so because &lt;strong&gt;I am an Administrator on my own machine&lt;/strong&gt;. The actual &lt;em&gt;Administrator &lt;/em&gt;account has been disabled, and I really don’t want to have to re-enable the account to figure this out. There’s got to be a remedy for this. Have no fear, because there is, and it’s not too bad.&lt;/p&gt;

&lt;p&gt;1. Right click on the folder and select &lt;strong&gt;Properties&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;2. Select the &lt;strong&gt;Security&lt;/strong&gt; tab. &lt;/p&gt;

&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/10/delete_properties_security.png"/&gt;&lt;/p&gt;

&lt;p&gt;3. Under &lt;strong&gt;Group or user names&lt;/strong&gt;, click &lt;strong&gt;Edit…&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;4. Click &lt;strong&gt;Add…&lt;/strong&gt; to add yourself to the list of users and give yourself full control on the folder. &lt;/p&gt;

&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/10/delete_properties_permissions.png"/&gt;&lt;/p&gt;

&lt;p&gt;You should now be able to freely delete the folder without any nasty warnings or messages.&lt;/p&gt;

&lt;p&gt;See Also&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.howtogeek.com/howto/windows-vista/how-to-delete-a-system-file-in-windows-vista/"&gt;How-to Geek: How to Delete a System File in Windows 7 of Vista&lt;/a&gt; – &lt;em&gt;Command line example&lt;/em&gt; &lt;/li&gt;
&lt;/ul&gt;</description><link>http://jarrettmeyer.com/post/11908707833</link><guid>http://jarrettmeyer.com/post/11908707833</guid><pubDate>Tue, 25 Oct 2011 11:06:13 -0400</pubDate><category>win</category></item><item><title>Aliases in Windows Command Line</title><description>&lt;p&gt;A few weeks back, &lt;a href="http://wekeroad.com/" target="_blank"&gt;Rob Conery&lt;/a&gt; posted on &lt;a href="http://wekeroad.com/2011/10/06/flex-the-power-of-your-mac-terminal" target="_blank"&gt;how to setup aliases in the Mac terminal&lt;/a&gt;. Guess what! It’s also quite easy to do the exact same thing in Windows. You can tell that the command is old, just because of the name: &lt;a href="http://en.wikipedia.org/wiki/DOSKey" target="_blank"&gt;doskey&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want your settings to always load, you’ll need to create a startup script. I’ve named mine autorun.cmd, and I’ve placed in C:\util. The file (shortened) looks like this.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/10/command_line_autorun.png"/&gt;&lt;/p&gt;
&lt;p&gt;You then need to setup your &lt;a href="http://en.wikipedia.org/wiki/Cmd" target="_blank"&gt;terminal window&lt;/a&gt; to load with the /k option. I use Console, so here’s what my shell settings look like.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://c85212.r12.cf2.rackcdn.com/jarrettmeyer.com/content/2011/10/console_shell_settings_autorun_cmd.png"/&gt;&lt;/p&gt;
&lt;p&gt;It’s pretty easy, and it can save you tons of time and keystrokes. Don’t be afraid of the command line, Windows users. It is your (seldom-used) friend.&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/11576734010</link><guid>http://jarrettmeyer.com/post/11576734010</guid><pubDate>Mon, 17 Oct 2011 14:11:19 -0400</pubDate><category>Windows</category></item><item><title>Rest in peace, Steve Jobs</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_lsmcynNTCd1qch9sio1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Rest in peace, Steve Jobs&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/11081799812</link><guid>http://jarrettmeyer.com/post/11081799812</guid><pubDate>Wed, 05 Oct 2011 20:49:35 -0400</pubDate></item><item><title>Updates to VS 2011</title><description>&lt;p&gt;
  I don’t write a lot of desktop applications, but I do write enough to dislike having both VS and Blend open at the same time. Then I read &lt;a href="http://lostechies.com/gabrielschenker/2011/09/16/build-conferenceday-3/"&gt;this post&lt;/a&gt; from Gabriel Schenker.
&lt;/p&gt;

&lt;blockquote&gt;
  &lt;h3&gt;The new XAML editor in VS 2011&lt;/h3&gt;

  &lt;p&gt;
    If you have worked with WPF or Silverlight in Visual Studio 2010 or 2008 you know that the XAML editor was extremely slow and limited in its functionality. Now that has changed dramatically in VS 2011. First of all the new XAML editor is backed by the same engine (or at least part of it) as Expression Blend. The editor now runs in its own process to not compromise the stability and availability of VS. The editing capabilities have tremendously improved and members of the VS team confirmed me that they are tuning the editor as much as possible and make it performing well also in very large project with many assets.
  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
  It seems MS is getting smarter about its product lines, and using the good stuff from other applications. This can only be a good thing.
&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/10314886963</link><guid>http://jarrettmeyer.com/post/10314886963</guid><pubDate>Sat, 17 Sep 2011 10:16:33 -0400</pubDate></item><item><title>Refactoring a Controller Action</title><description>&lt;p&gt;
  &lt;em&gt;This is a response to &lt;a href="http://www.simple-talk.com/dotnet/.net-framework/writing-maintainable-code/"&gt;Writing Maintainable Code&lt;/a&gt; by &lt;a href="http://www.simple-talk.com/author/michael-williamson/"&gt;Michael Williamson&lt;/a&gt;. First off, I believe 100% in everything the author wrote. My only problem with his example is that he didn’t go nearly far enough down the refactoring rabbit hole.
&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Original Code&lt;/h3&gt;

&lt;p&gt;
  So let’s start with this original code, as presented by the author. I’ll warn you a couple of things.
&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;It is quite awful.&lt;/li&gt;
  &lt;li&gt;It is typical of what I see when I look at other developers MVC code.&lt;/li&gt;
&lt;/ol&gt;&lt;pre&gt;
public class ArchiveController : Controller
{
  private readonly ISession m_Session;

  public ArchiveController(ISession session)
  {
    m_Session = session;
  }

  public ActionResult Index(FormCollection form)
  {
    var sds = form["start-date"];
    var sd = DateTime.MinValue;
    if (sds != null)
    {
        if (DateTime.TryParse(sds, out sd))
        {
        }
        else if (sds == "now")
        {
            sd = DateTime.Now;
        }
    }

    var eds = form["end-date"];
    var ed = DateTime.MaxValue;
    if (eds != null)
    {
        if (DateTime.TryParse(eds, out ed))
        {
        }
        else if (eds == "now")
        {
            ed = DateTime.Now;
        }
    }

    var hss = m_Session.QueryOver&lt;HatSale&gt;().Where(h =&gt; h.DateTime &gt;= sd).Where(h =&gt; h.DateTime &lt;= ed).List();

    var ahwpm = hss.GroupBy(h =&gt; h.DateTime.Month).Select(g =&gt; new {W = g.Key, Avg = g.Average(s =&gt; s.Hat.Width)});

    return View(new {Hss = hss, Ahwpm = ahwpm});
  }
}  
&lt;/pre&gt;

&lt;p&gt;
  Yes, the code compiles. Yes, the code works. But compiling and working isn’t the point (even though some developers think you’re done at this point). Compiling and working are just the first steps of a bigger process. We want code that is readable and maintainable over the long term. What are you going to see when you come back to it in 1, 3, 6, or 12 months (or longer)? &lt;strong&gt;No, the answer is not, “Let’s add a bunch of in-line comments.”&lt;/strong&gt; The answer is refactor the working code into better code. Make smaller, reusuable, well-named methods.
&lt;/p&gt;

&lt;h3&gt;Refactored Code - Part 1&lt;/h3&gt;

&lt;p&gt;
  The original author points out the following (all valid) problems with the original code.
&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;The class is called &lt;code&gt;ArchiveController&lt;/code&gt; – what’s in this archive?&lt;/li&gt;
  &lt;li&gt;The variables aren’t named well, for instance, what does &lt;code&gt;ahwpm&lt;/code&gt; mean?&lt;/li&gt;
  &lt;li&gt;The logic that reads start-date and end-date from the form is duplicated.&lt;/li&gt;
  &lt;li&gt;What does &lt;code&gt;DateTime&lt;/code&gt; on a hat sale represent?&lt;/li&gt;
  &lt;li&gt;There are bits of NHibernate querying and LINQ all on one unreadable line.&lt;/li&gt;
  &lt;li&gt;The method is long, and you feel you have to read the whole thing to begin to understand what’s going on.&lt;/li&gt;
  &lt;li&gt;The method operates at many layers of abstraction – it’s parsing strings, accessing the database, and doing some calculations.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
  The author then presents this updated solution.
&lt;/p&gt;

&lt;pre&gt;
public class SalesArchiveController : Controller
{
  private readonly ISession m_Session;
 
  public SalesArchiveController(ISession session)
  {
      m_Session = session;
  }

  public ActionResult Index(FormCollection form)
  {
    var startDate = ParseStartDate(form);
    var endDate = ParseEndDate(form);

    var hatSales = FetchHatSalesInDateRange(startDate, endDate);

    var averageHatWidthsPerMonth = CalculateAverageHatWidthsPerMonth(hatSales);

    return View(new {HatSales = hatSales, AverageHatWidthsPerMonth = averageHatWidthsPerMonth});
  }

  private DateTime ParseStartDate(FormCollection form)
  {
    return ParseDateParameterOrNull(form, "start-date") ?? DateTime.MinValue;
  }

  private DateTime ParseEndDate(FormCollection form)
  {
      return ParseDateParameterOrNull(form, "end-date") ?? DateTime.MaxValue;
  }
 
  private DateTime? ParseDateParameterOrNull(FormCollection form, string key)
  {
    var dateString = form[key];
    if (string.IsNullOrEmpty(dateString))
    {
        return null;
    }
    DateTime dateTime;
    if (DateTime.TryParse(dateString, out dateTime))
    {
        return dateTime;
    }
    if (dateString == "now")
    {
        return DateTime.Now;
    }
    return null;
  }
 
  private IList&lt;HatSale&gt; FetchHatSalesInDateRange(DateTime startDate, DateTime endDate)
  {
      return m_Session
          .QueryOver&lt;HatSale&gt;()
          .Where(h =&gt; h.DateOfSale &gt;= startDate)
          .Where(h =&gt; h.DateOfSale &lt;= endDate)
          .List();
  }
 
  private IList&lt;MonthlyHatSales&gt; CalculateAverageHatWidthsPerMonth(IList&lt;HatSale&gt; hatSales)
  {
      return hatSales
          .GroupBy(sale =&gt; sale.DateOfSale.Month)
          .Select(group =&gt; new MonthlyHatSales
          {
              AverageHatWidth = group.Average(sale =&gt; sale.Hat.Width),
              Month = group.Key
          })
          .ToList();
  }
 
  public class MonthlyHatSales
  {
      public int Month { get; set;}
      public double AverageHatWidth { get; set; }
  }
}  
&lt;/pre&gt;

&lt;p&gt;
  Is the refactoring better? Absolutely. Look at the action method now. Without a single inline comment, there is absolutely no doubt about what is going on, and there isn’t a single in-line comment. &lt;strong&gt;If you write clearly, you don’t need comments.&lt;/strong&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;em&gt;Maybe I should clarify that last sentence. You shouldn’t need comments for “what” your code is doing. “What” your code is doing will be self-discoverable when it is well written. I frequently find myself using “why” comments. “Why” am I solving the problem this way? Also, good comments in ugly code are better than no comments in ugly code. But the better solution is to not write ugly code in the first place.&lt;/em&gt; Anyway, here’s the refactored code.
&lt;/p&gt;

&lt;pre&gt;
var startDate = ParseStartDate(form);
var endDate = ParseEndDate(form);
var hatSales = FetchHatSalesInDateRange(startDate, endDate);
var averageHatWidthsPerMonth = CalculateAverageHatWidthsPerMonth(hatSales);
return View(new {HatSales = hatSales, AverageHatWidthsPerMonth = averageHatWidthsPerMonth});  
&lt;/pre&gt;

&lt;p&gt;
  My problems aren’t with what the author did; my problem is with how those aims were accomplished.
&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Why is &lt;code&gt;MonthlyHatSales&lt;/code&gt; a nested class? What about this class makes it specific or dependent on the parent controller class?&lt;/li&gt;
  &lt;li&gt;Calculating the averages should be done as part of an extension method.&lt;/li&gt;
  &lt;li&gt;Why is the author parsing from the form collection?&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
  Nested classes that have no dependency on their parent classes really bother me. More often than not, when I see a nested class, there’s no explanation beyond the original developer being to lazy to open up a new source file.
&lt;/p&gt;

&lt;p&gt;
  I think the last point is the biggest though. If you’re parsing the FormCollection, it shows me that you really don’t know the guts of MVC. You’re doing something that the architecture already does for you, and you’re not doing it as well as the architecture.
&lt;/p&gt;

&lt;h3&gt;Refactored Code - Part 2&lt;/h3&gt;

&lt;p&gt;
  Have you seen &lt;a href="http://mvc.fubu-project.org/"&gt;FubuMVC&lt;/a&gt;? Even if you’re not using it, you should learn about it. The FubuMVC architecture has a wonderful pattern called one-model-in-one-model-out. I don’t use FubuMVC, but I love that idea. I copy it on my ASP.NET MVC projects. You have no idea how much this can clean up your code. First, let’s create an input model. We’re going to let the MVC model binder do the work for us. We’re also going to use proper properties (not auto-properties), since there is a bit of logic in the property getter.
&lt;/p&gt;

&lt;pre&gt;
public class SalesArchiveIndexInput
{
  private DateTime? startDate;
  private DateTime? endDate;
  
  public DateTime? StartDate 
  { 
    get { return startDate ?? DateTime.MinValue; }
    set { startDate = value; }
  }
  
  public DateTime? EndDate 
  { 
    get { return endDate ?? DateTime.MaxValue; }
    set { endDate = value; }    
  }
}
&lt;/pre&gt;

&lt;p&gt;
  Now, we don’t need any parsing logic in our controller action at all, and we don’t need to worry about coercing a null value.
&lt;/p&gt;

&lt;p&gt;
  I’m going to leave the last two methods in there, but only because I don’t know the rest of the application. My bet is that the last method should be an extension method. They have no dependencies on the controller itself. They only depend on having an &lt;code&gt;ISession&lt;/code&gt; instance and their input parameters.
&lt;/p&gt;

&lt;pre&gt;
public class SalesArchiveController : Controller
{
  private readonly ISession m_Session;
 
  public SalesArchiveController(ISession session)
  {
    m_Session = session;
  }

  public ActionResult Index(SalesArchiveIndexInput form)
  {
    var hatSales = FetchHatSalesInDateRange(form.StartDate.Value, form.EndDate.Value);
    var averageHatWidthsPerMonth = CalculateAverageHatWidthsPerMonth(hatSales);
    return View(new { HatSales = hatSales, AverageHatWidthsPerMonth = averageHatWidthsPerMonth });
  }

  private IList&lt;HatSale&gt; FetchHatSalesInDateRange(DateTime startDate, DateTime endDate)
  {
    return m_Session
        .QueryOver&lt;HatSale&gt;()
        .Where(h =&gt; h.DateOfSale &gt;= startDate)
        .Where(h =&gt; h.DateOfSale &lt;= endDate)
        .List();
  }
 
  private IList&lt;MonthlyHatSales&gt; CalculateAverageHatWidthsPerMonth(IList&lt;HatSale&gt; hatSales)
  {
    return hatSales
        .GroupBy(sale =&gt; sale.DateOfSale.Month)
        .Select(group =&gt; new MonthlyHatSales
        {
            AverageHatWidth = group.Average(sale =&gt; sale.Hat.Width),
            Month = group.Key
        })
        .ToList();
  } 
}    
&lt;/pre&gt;

&lt;p&gt;
  Now, there is absolutely no question about what is going on in that controller action, and we’re not duplicating anything that the framework already can do for us.
&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/10199075207</link><guid>http://jarrettmeyer.com/post/10199075207</guid><pubDate>Wed, 14 Sep 2011 07:18:42 -0400</pubDate></item><item><title>MVC Action Result To Redirect To Return URL</title><description>&lt;p&gt;
  It doesn’t take too many MVC applications before you’ll see something like this in your URL bar.
&lt;/p&gt;

&lt;p&gt;
  &lt;img src="http://media.tumblr.com/tumblr_lqejtnIT5Q1qcrv2z.png" alt="URI with return value" title="URI with return value"/&gt;&lt;/p&gt;

&lt;p&gt;
  The default MVC project shows you a way to handle it, but it violates DRY if you use the idea of ReturnUrl in more than one place in your application. In my case, I’ve got just that problem. I’ve got an application where you can perform a single activity from multiple places, but I always want to send you back from whence you came. The good news is that this is really easy to accomplish with a custom action result.
&lt;/p&gt;

&lt;pre&gt;
public class RedirectToReturnUrlResult : ActionResult
{
  private readonly Func&lt;ActionResult&gt; funcIfNoReturnUrl;

  public RedirectToReturnUrlResult(Func&lt;ActionResult&gt; funcIfNoReturnUrl)
  {
    if (funcIfNoReturnUrl == null) throw new ArgumentNullException("funcIfNoReturnUrl");

    this.funcIfNoReturnUrl = funcIfNoReturnUrl;
  }

  public override void ExecuteResult(ControllerContext context)
  {
      string returnUrl;
      if (TryGetReturnUrl(context, out returnUrl))
      {
        new RedirectResult(returnUrl).ExecuteResult(context);                
      }
      else
      {
        funcIfNoReturnUrl().ExecuteResult(context);
      }
  }

  private bool TryGetReturnUrl(ControllerContext context, out string returnUrl)
  {
      try
      {
        var queryString = context.HttpContext.Request.QueryString;
        returnUrl = queryString["ReturnUrl"];
        return !string.IsNullOrEmpty(returnUrl);
      }
      catch (Exception ex)
      {
        returnUrl = null;
        return false;
      }
  }
}  
&lt;/pre&gt;

&lt;p&gt;
  The usage is pretty simple, too. We just need to give it a default action result to execute if no “ReturnUrl” query string is found.
&lt;/p&gt;

&lt;p&gt;
  &lt;img src="http://media.tumblr.com/tumblr_lqejy7udxK1qcrv2z.png"/&gt;&lt;/p&gt;

&lt;p&gt;
  See? I told you it was easy.
&lt;/p&gt;</description><link>http://jarrettmeyer.com/post/9563677876</link><guid>http://jarrettmeyer.com/post/9563677876</guid><pubDate>Mon, 29 Aug 2011 19:28:53 -0400</pubDate><category>a</category><category>cs</category><category>code</category></item></channel></rss>

