Friday, November 11, 2016

Running Web.Config Transforms on Build

Web application deployment typically involves transforming the build depending on the build target.  Typically Visual Studio only runs the standard transforms on publish of the web application (publish profiles).  This can be confusing and frustrating as many expect a different behavior.  It seems intuitive that transforms would be ran on build. 

The following is a simple recipe you can follow to ensure that MS Build will run the correct build target transforms on build.  In the steps below you'll notice it is suggested that the Web.Config in the project directory be removed from source control.  This is because each time you change configuration and build, the web config will be updated.   

  1. In Visual Studio, from the Build menu, open Configuration Manager.  At this point you can add build targets for each one of your environments.

Do what make sense, but a typical set of build targets may look something like this :
  • Debug
  • Staging
  • Pre-Production
  • Release

  1. In your Visual Studio Project, add a folder called Config 
    1. Copy your current Web.Config and its children Web.Debug.config & Web.Release.Config into the new Config folder.  Delete the old files and remove them from source control.
    2. Add a new file Web.($BuildTarget).config named to match your additional build targets by copying one of the existing transforms.

  1. Add a pre-build step in Visual Studio under Project > Properties > Build Events where project folder refers to the name of your project folder where the original web configs existed.
    1. xcopy "$(ProjectDir)Config\*.*" "$(SolutionDir)\ProjectFolder" /Y
  2. Unload your Visual Studio Project and edit the .csproj files xml.
    1. Add an AfterBuild target to the very bottom of the file right before the closing </Project> tag

<Target Name="AfterBuild" Condition="'$(PublishProfileName)' == '' And '$(WebPublishProfileFile)' == ''"> 
    <TransformXml Source="Web.config" Transform="Web.$(Configuration).config" Destination="Web.config" />

Now each time a build is triggered, the web-config will be properly transformed.

Friday, October 28, 2016

Software Testing Group Discussion Notes

At the last Duluth .Net User Group meeting we had a group discussion around the topic of testing.  As an extension of that meeting I want to present a collection of information for folks who are just getting familiar with software testing.  The following is an outline of our discussion including links to more in depth articles.

Common Types of Software Testing:
  • Unit Testing
  • Integration Testing
  • End To End Testing
  • Smoke Tests

After briefly discussing the types of test we focused in on Unit Testing.

Unit testing:
We loosely defined unit testing as “tests that can run on a small piece of the code base, isolated from external dependencies”. Every software decision has a trade-off so we tried to list out the benefits of unit testing weighed against its cost.  

  • Regression safety, provides a level of confidence in the code
  • Having tests gives you a tool to put more tests in place when you find bugs
  • Gives other developers a starting place to understand the code
  • Can be used as a part of the continuous delivery feedback loop to know if code is stable
  • Can save time debugging the code
  • Adds overhead to changing code
  • At least doubles the code base
  • Have to maintain test setup code and fake data
  • Adds upfront development time

Unit testing styles can be broken into a few categories as well, defined by looking at how a programmer approaches testing and what tools they use.

Styles of Testing
  • Mockist
    • Make no distinction between mocks and stubs, and use a mocking framework for everything
  • Traditionalist
    • Use stubs when necessary mostly avoiding mocks
  • TDD (Test Driven Development)
    • Follow the guiding principle of writing tests first before any code is written
  • BDD (Behavior Driven Development)
    • Believe that code should be tested focusing on the codes domain language and user requirements
  • Code First - Test Last Developers
    • These developers realize the importance of tests but shun the dogma of TDD & BDD, writing the tests after they solve the problem at hand.

The discussion turned to looking at how architecture of code affects testing.  We found that many of us had worked with code bases where testing was impossible without some level of refactoring.  The conclusion was that code must be designed to be tested.  

Frameworks or Patterns that Make Testing Easier
  • MVC - Model View Controller
  • MVVM - Model View View Model
  • MVP - Model View Presenter
    • All of these patterns separate out the view making testing simpler
  • IOC - Inversion of Control
    • A pattern that allows for easy substitution of code dependencies

The group consensus was that while testing can be tedious and add overhead, it provides a margin of confidence for development that cannot be ignored nor denied.

Dive Deeper!

Saturday, October 15, 2016

Flexible Forms with AlpacaJs

At work recently we decided to implement our own custom forms.  The requirement was that we needed to be able to switch out our standard forms with variants so we could do A-B testing.  We already make use of Formstack for one off custom forms, so we decided to look into what it would take to utilize FS.  As requirements matured we realized FS was not going to work for our needs.

We finally decided on AlpacaJs which is a jQuery plugin for dynamic forms.  It allows us to store a standardized JSON form schema in our database and dynamically then load these forms into our site.  The library is being actively maintained on GitHub check it out!  Alpaca is not without issues, but overall the concept is solid and it's working well for our needs.

Monday, August 22, 2016

Entity Framework Code First - Don't Initialize Navigation Properties

At work we've been using Dapper.Net as our ORM.  For several months I felt that if we were using Entity Framework for our ORM our velocity would increase.  Recently my feelings on this have started to change as I've realized that Dapper doesn't suffer the restrictions of large ORMs.

Entity Framework is too much magic.  Let me provide the most recent example of that magic that wasted 3 hours of my life.

Code first gives us the ability to work with POCOs, which is nice.  Generally, when using EF I turn off lazy loading and proxy creation and I don't use virtual collections.  I new collections up in the constructor.  While I was doing that I also followed the law of least surprise.  Objects should be ready to use when created, so on a POCO I would also new up any child objects, such as the navigation property in the below example.  

//An example of what you should not do!
public class Contact  
   public Contact(){      
     PhoneNumbers = new List<PhoneNumber>();  
     Address = new Address();  
   public int Id { get; set; }  
   public string UserName { get; set; }  
   public List<PhoneNumber> PhoneNumbers {get; set; }  
   public Address Address { get; set; }  

Those of you that use EF all the time probably caught the above error.  Initializing the collection is fine, but initializing the navigation property is a problem.  It breaks EF's builtin relationship fix-up mechanism.  We've assigned an empty object to our navigation property and so now when trying to eager load the things we'll end up with an empty object instead of the expected entity from the db.

The rule then becomes, DO NOT new up navigation properties on your POCOs!  This is just a small example why I'm starting like Dapper more :)

Saturday, August 20, 2016

Pull Request /ˈedəkət,ˈedəˌket/

Over the years I've seen many unproductive threads on the net revolving around projects that are accepting pull requests.  In general when both project maintainers and contributors use their manners everyone stays happier.  When you read some project threads it often seems we aren't very kind to each-other.  Repudiate the code if you must, just don't offend the contributor.  That can be a difficult balance to strike!

The other day while reading in the Thinktecture.IdentityServer3 repo on GitHub, I found a list of links regarding pull request etiquette.  I found them so helpful I wanted to re-share them here.

Have you ever read a Linus Torvalds rant?  If you question whether or not you're interacting with your fellow coders correctly, read one of his rants and then NEVER do react like that!

Sunday, February 28, 2016

MS-Test Code Coverage in Jenkins Build Server

One interesting aspect of working on a small team that does not yet have a dev-ops position is that we all get to have a hand in different aspects of what dev-ops entails.  We use Jenkins an open source Java powered build server. If you aren't aware of what Jenkins is all about, read up on it.

Our team has been creating, testing and refactoring our code, and as we do that we've been focusing on increasing code quality through unit testing.  Passing tests turn coding into a game and as with any good game, you have to have your stats!  Jenkins was already happily running our tests, but the boss was wondering if he could see our code coverage and test reports.  How hard could that be to add?  :)

I decided I'd dive into it to see if I could figure it out.  It turns out
that once you know what you're doing, it's a pretty simple process.  First off, you'll need to ensure you have all the right Jenkins plugins.

Then it's simply a matter of following plugin instructions.  Our build follows this process.
  • Build projects from source control using MS Build
  • Clear the previous TestResults folder from the workspace with a batch command

  • Run unit tests with VSTest.console
    • Specify a settings file for .runsettings to exclude any assemblies you don't want to be shown in the coverage report
    • Enable Code Coverage

  • Run PowerShell Command for code coverage data conversion as described on the MS-Test plugin page.   

  • Post-build Action - Publish xUnit test result report
    • Published as MSTest-Version N/A (default) Pattern
    • Published as MSTest test result report 

The end result is a series and graphs :)

Project Overview Charts

Jenkins is powerful, if not more than a little plugin happy...  We are mainly a .NET shop at work, so while I feel Jenkins is a little disjointed. I'm imagining that if you're using it to build Java projects things may be slightly easier to configure.  Nevertheless, the more familiar I get with it the more I'm liking it.

Saturday, January 30, 2016

Editing Collections in MVC

At work we've been rebuilding some of our core applications.  As a part of that effort I've been working on an internal MVC 4 solution used to provision our multi-tenant application.  The application fits nicely into the MVC pattern, it's a simple CRUD app.  The user fills in forms and posts them to the server.  Everything was great until I started working on more complex forms that are for aggregate root objects.  How do you edit the child collections on the parent object without round tripping to the server?  In this scenario we want to edit the child collections and post the object back to the server one time.

For development speed I didn't want to introduce the complexity and overhead of Angular 1.x or 2.x, and I didn't want to lose the strong typing and unobtrusive client side validation that .NET MVC provides.  While Angular has its place, it feels like overkill to need another client side framework to edit a few collections in a form.  To keep complexity low I wanted to find a pattern that used as little java-script as possible and would be usable throughout the application.

After digging into the issue I found several blog posts on the topic, among those the two below explain the principles of how this works.

Phil Hack - 2008 - Model Binding To A List

Ivan Zlatev - 2011 Series - Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 1: ASP.NET MVC Views

The heart of the issue revolves around MVC model binding.  The default model binding uses the object and property name as the html id and name attribute.  For example, say we have an object called Asset with a property Url that is placed into our view using the EditorFor Html helper.

This would result in raw HTML that looks like this...

<div class="form-group">
    <label class="control-label col-md-2" for="Asset_Url">URL *</label>
    <div class="col-md-10">
        <input class="form-control text-box single-line" data-val="true" data-val-required="The URL * field is required." id="Asset_Url" name="Asset.Url" type="text" value="~/Content/DealerContent/23138/site.css">
        <span class="field-validation-valid text-danger" data-valmsg-for="Asset.Url" data-valmsg-replace="true"></span>

Notice the id, for, name, data-val-required and data-valmsg-for all our object name and property in them.  Also be aware that using EditorTemplates and nesting your model through the templates will affect this naming scheme.  For example in another of my apps I have an id that looks like this, "Client_ClientSecrets_0__Description". These are the attributes that MVC model binding and unobtrusive client side validation tie into. If you write out a collection you'll notice that an index position gets added into the attribute.

<div class="col-md-10">
    <input class="form-control text-box single-line" data-val="true" data-val-required="The URL * field is required." id="Assets_0__Url" name="Assets[0].Url" type="text" value="~/Content/DealerContent/23138/site.css">
    <span class="field-validation-valid text-danger" data-valmsg-for="Asset[0].Url" data-valmsg-replace="true"></span>

MVC model binding knows you have a collection when it picks up the index in the html attribute names. It's smart, but finicky. If your indexes get out of sequence when your form posts you'll find collections that are missing items.

To recap and boil the problem down, when editing collections client side the html input elements must be formatted as the model binder expects, and the collection index must stay in order.

 As a side note, we are also interested in keeping the unobtrusive client side validation working. The wiring for validation runs after the page loads, therefor items added dynamically into the page are unknown by by client side validation. To get around this we'll add in little extra jQuery magic.  Now onto the code.

One significant thing to note is that this solution doesn't use any C# html helpers.  We use a simple for loop with the editor template to write out our collection.  The for our partial template item, the editor template is reused.  If you want to avoid loading yet another JavaScript library, this may be a useful pattern!