Database Migrations and Seeding in ASP.NET Core

Tuesday, September 20, 2016 by K. Scott Allen

There is an instant in time when an ASP.NET application is fully alive and configured but it still held in check and waiting for a signal from the starter’s gun. This moment exists between the lines of code in Program.cs, and it is here where I’ve found a nice place to automatically run database migrations and seed a database based on command line arguments to the program.

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseIISIntegration()
        .UseStartup<Startup>()
        .Build();

    ProcessDbCommands(args, host);

    host.Run();
}

ProcessDBCommands is the method I use in the above code, and the logic here can be as simple or as complicated as you need. In my case, I’m just going to look for keywords in the arguments to drop, migrate, and seed the database. For example, running “dotnet run dropdb migratedb seeddb” will execute all three options against the configured database.

private static void ProcessDbCommands(string[] args, IWebHost host)
{
    var services = (IServiceScopeFactory)host.Services.GetService(typeof(IServiceScopeFactory));

    using (var scope = services.CreateScope())
    {
        if (args.Contains("dropdb"))
        {
            Console.WriteLine("Dropping database");
            var db = GetLeagueDb(scope);
            db.Database.EnsureDeleted();
        }
        if (args.Contains("migratedb"))
        {
            Console.WriteLine("Migrating database");
            var db = GetLeagueDb(scope);
            db.Database.Migrate();
        }
        if (args.Contains("seeddb"))
        {
            Console.WriteLine("Seeding database");
            var db = GetLeagueDb(scope);
            db.Seed();
        }
    }        
}

private static LeagueDb GetLeagueDb(IServiceScope services)
{
    var db = services.ServiceProvider.GetRequiredService<LeagueDb>();           
    return db;
}

A couple notes on the above code.

IWebHost gives us access to a fully configured environment, so connection strings and services are available just as they are inside the rest of the post-startup application code.

The db.Database.EnsureDeleted and db.Database.Migrate methods are built-in APIs for EF Core. The Seed method, on the other hand, is a custom extension method.

The Troubles with JavaScript Classes

Tuesday, September 13, 2016 by K. Scott Allen

Over the summer I gave a talk titled “The New Dragons of JavaScript”. The idea was to provide, like the cartographers of the Old World, a map of where the dragons and sea serpents live in the new JavaScript feature landscape. These mythological beasts have a tendency to introduce confusion or pain in software development.  

One area I covered were the quirks you might run into with JavaScript classes. Some introductions explain how classes work by describing the de-sugaring a transpiler applies to transform a class into the classical constructor function and prototype manipulation we’ve used in JavaScript for many years.

class Employee {
    constructor(name) {
        this._name = name;
    }

    doWork() {
        return `${this._name} is working`;
    }
}

// above code becomes ...

let Employee = function(name) {
    this._name = name;
};

Employee.prototype = {
    doWork: function() {
        return `${this._name} is working`;
    }
}

Constructor functions and prototypes are a useful mental model to have at times, but also leads to trouble because classes aren’t exactly like using constructor functions. For example, functions in JavaScript will hoist, but classes do not. If you ever want to push the definition of a small utility class to the bottom of a file and try to use the class in the code at the top of the file, you’ll be setting yourself up for an error.

// this code works
const e = new Employee();

function Employee() {

}

// this code produces a ReferenceError
const e = new Employee();

class Employee {

}

Technically, classes (and variables declared with let and const) do hoist themselves, but they hoist themselves into an area the early specs referred to as the “temporal dead zone”. Accessing a symbol in its TDZ creates a RefernceError.  As an aside, “Temporal dead zone” is, I think, one of the greatest computer science terms ever conceived and should also be the title of a Hollywood film starring Mark Wahlberg.

Another difference between creating an object using a class and creating an object with a constructor function is in reflective code. It’s easy to discover the methods of an object instantiated with a constructor function using a for in loop.

const Human = function () { }
Human.prototype.doWork = function () { };

let names = [];
for (const p in new Human()) {
    names.push(p);
}
// ["doWork"]

The same code won’t work when using a class definition.

class Horse {
    constructor() {}            
    doWork() { }
}

names = [];
for (const p in new Horse()) {
    names.push(p);
}
// []

However, it is possible to get to the methods of a class using some Object APIs.

names = [];
const prototype = Object.getPrototypeOf(new Horse());
for(const name of Object.getOwnPropertyNames(prototype)) {
    names.push(name);
}
// ["constructor", "doWork"]

Coming soon – The Troubles with Modules.

Previously in this series – The Trouble with JavaScript Arrow Functions

Combining HttpPost and ValidateAntiForgeryToken

Thursday, September 8, 2016 by K. Scott Allen

I’ve been kicking around the idea of combining [HttpPost] and [ValidateAntiForgeryToken] in an application using authentication cookies. Both attributes typically appear together to prevent cross-site request forgeries in MVC applications using cookie based authentication. The result looks like the following.

[HttpPostWithValidAntiForgeryToken]
public IActionResult Edit(Input model)
{
    // ... 
}

And the attribute definition is as follows.

public class HttpPostWithValidAntiForgeryToken
    : Attribute, IActionHttpMethodProvider, IFilterFactory
{
    private readonly HttpPostAttribute _postAttribute;
    private readonly ValidateAntiForgeryTokenAttribute _antiForgeryAttribute;

    public HttpPostWithValidAntiForgeryToken()
    {
        _postAttribute = new HttpPostAttribute();
        _antiForgeryAttribute = new ValidateAntiForgeryTokenAttribute();
    }

    public IEnumerable<string> HttpMethods => _postAttribute.HttpMethods;

    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
    {
        return _antiForgeryAttribute.CreateInstance(serviceProvider);
    }

    public bool IsReusable => _antiForgeryAttribute.IsReusable;
}

With the new attribute, a plain [HttpPost] should never appear in the application, and a unit test using reflection could enforce the rule.

Don't Throw Away All Those web.config Settings

Tuesday, September 6, 2016 by K. Scott Allen

ASP.NET Core might not use a complicated hierarchy of XML configuration files anymore, but if you host under IIS, then IIS and web.config are still the best of friends. There is some XML configuration required to run Core under IIS, specifically the part to reverse proxy all incoming requests over to the ASP.NET Core module and ultimately into the Kestrel server.

Other pieces of web.config still work in the new world of ASP.NET, too. For example, IIS will still honor rewrite rules in web.config.

Here is a sample web.config to enforce lower case URLs that also proxies to the ASP.NET Core Module.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>

    <rewrite>
      <rules>
        <rule name="Convert to lower case" stopProcessing="true">
          <match url=".*[A-Z].*" ignoreCase="false" />
          <action type="Redirect" url="{ToLower:{R:0}}" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
    
    <handlers>
      <add name="aspNetCore" path="*" verb="*" 
           modules="AspNetCoreModule" resourceType="Unspecified"/>
    </handlers>
    
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" 
                stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" 
                forwardWindowsAuthToken="false"/>
    
  </system.webServer>
</configuration>

The Troubles with JavaScript Arrow Functions

Thursday, September 1, 2016 by K. Scott Allen

Over the summer I gave a talk titled “The New Dragons of JavaScript”. The idea was to provide, like the cartographers of the Old World, a map of where the dragons and sea serpents live in the new JavaScript feature landscape. These mythological beasts have a tendency to introduce confusion or pain in software development.

Arrow functions have surprised me with the amount of turmoil they’ve created. At first glance, they seem so easy, like when multiplying the numbers in an array by 2.

const numbers = [1, 2, 3];
const result = numbers.map(n => n * 2);
// produces [2,4,6]

But even a simple map operation can run into problems if the code tries to map each element to an object literal using the wrong syntax.

const numbers = [1, 2, 3];
const result = numbers.map(n => { value: n });
// produces [undefined], [undefined], [undefined]

The problem in the above code is that the opening curly brace of the arrow function makes JavaScript think there is a block of code to execute instead of a simple object literal expression to evaluate. The result is an array of undefined. In this scenario the code either needs an explicit return statement, or to parenthesize the object literal.

const result = numbers.map(n => ({ value: n }));
// [{value: 1}, {value:2}, {value:3}]

Ironically, most problems developers encounter with arrow functions center around the problem arrow functions attempt to solve. The slippery JavaScript this pointer. A bit of casual reading about arrow functions will tell you how arrow functions capture the this reference from their lexical environment. With arrows, you can write code like the following without worrying about explicitly capturing this into a local variable.

const adder = {
    sum: 0,
    add(numbers) {
        numbers.forEach(n => {
            this.sum += n;
        });
    }

};

adder.add([1, 2, 3]);
// adder.sum === 6

However, it’s easy to write code that assumes the wrong environment. In the following code we have an arrow function inside an arrow function, so the this reference will not be the adder object, but whatever scope the adder object lives in.

const adder = {
    sum: 0,
    add: (numbers) => { // scope here is important
        numbers.forEach(n => {
            this.sum += n;
        });
    }

};

adder.add([1, 2, 3]);
// adder.sum === 0

The biggest sea dragon on the map in the arrow function waters is highlighted in the “NOTE” section of 14.2.16 of the spec. The takeaway here is that we cannot change the this reference inside of an arrow function. The reference is fixed, it’s baked, it’s  static and permanent. There are implications for two types of code. First is the type of code that expects to manipulate this using bind, call, or apply.

const adder = {
    sum: 0
};

const add = (numbers) => numbers.forEach(n => this.sum += 1);

adder.add = add.bind(adder);

adder.add([1, 2, 3]);
// adder.sum === 0

The second type of code is code that expects someone else to setup this for a call. I first experienced the brain teaser of unexpected this values writing arrow functions with Jasmine. Jasmine sets this to a context object for sharing state between test setups and asserts. Arrow functions, Jasmine contexts and regular functions mix into a broken cocktail. The same problem can arise with DOM event handlers.

it("this is not what you might expect", () => {

    // .. this?

});

Summary

Arrow functions are not a replacement for regular functions in JavaScript. There are situations where arrow functions do not work as expected. I’m not giving up on arrow functions, I still use them when possible. However, I do lament the fact that I still need to fret over every use of this in JavaScript code.

Keeping a Clean Startup.cs in Asp.Net Core

Tuesday, August 30, 2016 by K. Scott Allen

In some applications the Configure and ConfigureServices methods of Startup.cs can become unwieldy. It’s not complicated logic, but with all the middleware and services and options to configure, the methods become long and messy.

I prefer to keep a series of simple, one-line method calls inside of both methods.

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddCustomizedMvc();
    services.AddCustomizedIdentity();
    services.AddDataStores();
    // ...
}

All of the details for these method calls live inside extensions methods for IApplicationBuilder or IServiceCollection. Here’s an example. 

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddCustomizedMvc(this IServiceCollection services)
    {
        var locationFormat = @"Features\Shared\{0}.cshtml";
        var expander = new ViewWithControllerViewLocationExpander();

        services.AddMvc()
           .AddRazorOptions(options =>
           {
               options.ViewLocationFormats.Clear();
               options.ViewLocationFormats.Add(locationFormat);
               options.ViewLocationExpanders.Add(expander);
           });

        return services;
    }

    // ...
}

The New LINQ Fundamentals

Wednesday, August 17, 2016 by K. Scott Allen

The first course I ever made for Pluralsight was a LINQ Fundamentals course in 2008. I’ve received many great bits of feedback about the course over the last 8 years, but I’ve also learned a few things about teaching, presenting, and making courses during that time, too. Whenever I’m forced to listen to a clip from this early course I cringe. I sound like my speech was addled by sleeping pills and vodka.

A few months ago I decided it was time to make a new LINQ Fundamentals course, and this course was released just a few weeks ago. It’s mostly the same material as the original course, but with a more logical story arc and a perky sounding instructor.

I hope you enjoy watching the videos!

 

LINQ Fundamentals Training

My Pluralsight Courses

K.Scott Allen OdeToCode by K. Scott Allen
What JavaScript Developers Should Know About ECMAScript 2015
The Podcast!