Eric

.NET CLI Overview

In my post on migration from ASP.NET Core RC1 to RC2 I mentioned that there was a move from dnx to the .NET CLI. This post will be an overview this new platform and some of its capabilities.

Installation

If you already have ASP.NET Core RC2 installed then you already have the .NET CLI. If not head over to http://dot.net and click on Download .NET Core (or click here). This should take you to the proper download for your current OS. If you are on Windows and just want to install the command line tools the .NET Core SDK installer can be found here.

Installation Verification

Open a command prompt and run dotnet –version and if all is install and working you should see the version of the CLI you have installed. As of this writing I have version 1.0.0-preview1-002702 installed.

Hello World

Creating a new application that prints hello world to the console can be done without changing any code. First create a new directory and navigate  to the new directory. Next execute the following commands.

dotnet new
dotnet restore
dotnet run

After the last command you should see “Hello World!” printed by a .NET console application that was created with the new command. restore uses project.json (for now) to download the packages need for the application. Finally run compiles and executes the application.

Basic Concepts

You may see the dotnet command referred to as a driver. All this means is that it is used to execute other commands. For example dotnet new is telling the drive to execute the new command (also termed verb). The CLI comes with a set of common commands out of the box that can be extended with more commands via NuGet on per project or on the system path for machine level commands.

Common Commands

The following is a list of common command pull using dotnet help

Command Description
new Initialize a basic .NET project
restore Restore dependencies specified in the .NET project
build Builds a .NET project
publish Publishes a .NET project for deployment (including the runtime)
run Compiles and immediately executes a .NET project
test Runs unit tests using the test runner specified in the project
pack Creates a NuGet package

Adding Commands via NuGet

I am going to add the Entity Framework Core tool to the Hello World application created above as an example. To do this I am using Visual Studio Code, but you can use any editor you would like. All the changes needed will be made in project.json

In the dependencies section add the follow so that the needed packages will be downloaded when the dotnet restore command is run.

"Microsoft.EntityFrameworkCore.Tools": {
  "type": "build",
  "version": "1.0.0-preview1-final"
}

Next add a tool section. The tool section how CLI discovers available commands.

"tools": {
    "Microsoft.EntityFrameworkCore.Tools": {
       "imports": ["portable-net451+win8"],
       "version": "1.0.0-preview1-final"
   }
}

Finally in the frameworks section the imports needs to be change from dnxcore50. This change is needed for Entity Framework Core and may not be required if you are trying to use a different tool. The following is the full frameworks section.

"frameworks": {
  "netcoreapp1.0": {
    "imports": "portable-net451+win8"
  }
}

After running dotnet restore to download the new dependencies dotnet ef can be used to access Entity Framework Core commands. Running dotnet ef without any other arguments will display the Entity Framework Core command help.

                     _/\__
               ---==/    \\
         ___  ___   |.    \|\
        | __|| __|  |  )   \\\
        | _| | _|   \_/ |  //|\\
        |___||_|       /   \\\/\\
Entity Framework .NET Core CLI Commands 1.0.0-preview1-20901
Usage: dotnet ef [options] [command]
Options:
  -h|--help                        Show help information
  -v|--verbose                     Enable verbose output
  --version                        Show version information
  --framework <FRAMEWORK>          Target framework to load
  --configuration <CONFIGURATION>  Configuration under which to load
Commands:
  database    Commands to manage your database
  dbcontext   Commands to manage your DbContext types
  migrations  Commands to manage your migrations
Use "dotnet ef [command] --help" for more information about a command.

Wrapping Up

Here are a couple of good references if you are just getting started. First is the documentation for the .NET CLI which can be found here. The second is this post by Sam Basu.

Keep an eye for a future post on the process of creating new tool that can be used with the .NET CLI.

.NET CLI Overview Read More »

Angular 2 Template Driven Validation

Last week’s post covered model driven validation in Angular 2 and this week I will be looking at template driven validation. Template driven validation provides a simplified way to add validation without the need to directly use a control group. This is a great way to get up and running for simple form cases, and maybe more complex ones as well. I haven’t hit a case yet that wouldn’t work with either validation style.

Building a Template Form with Validation

I started with a simple form that contains labels and inputs for entering a name and email address that are bound to corresponding values in the associated model.

<form>
   <div class="form-group">
     <label for="name">Name</label>
     <input type="text" class="form-control" [(ngModel)]="name">
   </div>
   <div class="form-group">
     <label for="name">Email</label>
     <input type="text" class="form-control" [(ngModel)]="email">
   </div>
</form>

The next example is the same form with validation added.

<form #contactForm="ngForm">
   <div class="form-group">
     <label for="name">Name</label>
     <input type="text" class="form-control" ngControl="name" #nameControl="ngForm" [(ngModel)]="name" required minlength="3">
     <div [hidden]="nameControl.valid || !nameControl.errors || !nameControl.errors.required">Name is required</div>
     <div [hidden]="nameControl.valid || !nameControl.errors || !nameControl.errors.minlength">Min Length</div>
   </div>
   <div class="form-group">
     <label for="name">Email</label>
     <input type="text" class="form-control" ngControl="email" #emailControl="ngForm" [(ngModel)]="email" required>
     <div [hidden]="emailControl.valid || !emailControl.errors || !emailControl.errors.required">Email is required</div>
   </div>
</form>

The first change you will notice is that the form now has a name assigned using #contactForm=”ngForm”. In this case the name is not used, but it could be used to disable a submit button if any of the inputs the form contained didn’t have valid values. I am sure there are a lot more use cases as well.

On the inputs that need validation a controls name is assigned via ngControl=”name” and a name is assigned using #nameControl=”ngForm”. I had some trouble withe assigning names to my inputs at first I keep getting the following.

EXCEPTION: Cannot assign to a reference or variable!

The cause of the issue was that I was trying to use #name for the control name which was already a property on the model. Once I changed to #nameControl all worked fine.

For the input for name above required minlength=”3″ tells the Angular form that the input is required and must be at least three characters in length.

Displaying Validation

For the name input you can see that it has two divs used to show specific messages based on which validation condition failed.

<div [hidden]="nameControl.valid || !nameControl.errors || !nameControl.errors.required">Name is required</div>
<div [hidden]="nameControl.valid || !nameControl.errors || !nameControl.errors.minlength">Min Length</div>

I am not sure why, but when using the template style validation I had to check !nameControl.errors in addition to the specific error like !nameControl.errors.required or I would get an exception when the page tried to load. If your control doesn’t have more than a single validation then nameControl.valid would be a sufficient condition for showing validation messages.

Custom Validators

I am going to use the same email validator from last week with a few changes so can be used from a template. The following is the full class.

import {Control, NG_VALIDATORS, Validator} from '@angular/common';
import {Directive, Provider, forwardRef} from '@angular/core';

const EMAIL_VALIDATOR = new Provider(NG_VALIDATORS, { useExisting: forwardRef(() => EmailValidator), multi: true });

@Directive({
    selector: '[emailValidator]',
    providers: [EMAIL_VALIDATOR]
})
export class EmailValidator implements Validator {
    validate(control: Control): {[key: string]: any} {
        const emailRegexp = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
        if (control.value !== null && control.value !== "" && (control.value.length <= 5 || !emailRegexp.test(control.value))) {
            return { "email": true };
        }
        return null;
    }
}

The biggest difference is the @Directive decorator. The selector is the attribute that will be used to mark that an input needs to pass the specified validation. I am not 100% sure of the specifics of the provider, but the above works. This is another topic I need to explore more.

Using a Custom Validator

First in the model the validator must be imported.

import {EmailValidator} from './email-validator';

Then the validator needs to be added to the directives section of the @Component decorator.

@Component({
    selector: 'contact-detail',
    templateUrl: 'contact.detail.html',
    directives: [
        EmailValidator
    ],
    providers: [
        HTTP_PROVIDERS
    ]
})

To use in the view just add the emailValidator selector to the proper input.

<input type="text" class="form-control" ngControl="email" #emailControl="ngForm" [(ngModel)]="email" required emailValidator>

Finally add a div to display the error.

<div [hidden]="emailControl.valid || !emailControl.errors || !emailControl.errors.email">Email is invalid</div>

Wrapping Up

Using template driven validation you can quickly get a form validated without having to make changes outside of your template (unless you are using a custom validator). Angular 2 offers a lot of options when it comes to validation and where it should be put.

Angular 2 Template Driven Validation Read More »

Angular 2 Model Driven Validation

In this post a couple of weeks ago I covered Aurelia’s new validation plugin and I thought it would be good to see what Angular 2 has to offer validation wise. Angular’s offering is vastly different that Aurelia. Angular can use model driven or template driven validations. This post is going to look at the model driven style.

Forms

Angular forms is the framework’s way to handle groups of data entry that need support for data binding and validation among other things.

Building a Form with Validation

The first step to building a model driven form is import the classes that will be needed.

import {FormBuilder, ControlGroup, Validators} from '@angular/common';

Next add a variable for control group and setup the control group in the constructor of the class.

public contactForm: ControlGroup;

constructor(formBuilder: FormBuilder) {
    this.contactForm = formBuilder.group({
        name: ["", Validators.compose([Validators.required, Validators.minLength(3)])],
        email: ["", Validators.required]
    });
}

The above uses FormBuilder to define a name property that is required with a minimum length of three characters and an email property that is required. Later in the post I will add better email validation via customer validator.

Angular 2 only comes with required, minimum length, max length and pattern (match given regex) validators out of the box. Thankfully custom validators are pretty easy to implement.

Using a From with a View

Now that the form is setup the view needs to utilize it. The following is the code form the view.

<form class="form-horizontal" [ngFormModel]="contactForm">
  <div class="form-group">
      <label class="control-label">Name</label>
      <input type="text" ngControl="name" #name="ngForm" class="form-control">
      <div [hidden]="name.valid || name.pristine || !name.errors.required">Required</div>
      <div [hidden]="name.valid || name.pristine || !name.errors.minlength">Min Length</div>
  </div>
  <div class="form-group">
      <label class="control-label">Email</label>
      <input type="email" ngControl="email" #email="ngForm" class="form-control">
      <div [hidden]="email.valid || email.pristine || !email.errors.required">Required</div>
  </div>
</form>

First notice in the form tag [ngFormModel]=”contactForm” is used to bind the form to the control group crated in the model.

Instead of [(ngModel)]=”name” we use ngControl=”name” to bind the input box to the name control in the control group that was crated using the form builder above. #name=”ngForm” defines name as a variable that can be used later.

<div [hidden]=”name.valid || name.pristine || !name.errors.required”>Required</div>  is used to display validation errors to the user. This code is just saying to hide the div if name is valid or pristine (not changed by the user)  or if the validation error is not because the field is required. While this style works I much prefer Aurelia as it handles the extra work needed to automatically display validation errors.

Custom Validators

As I mention above I am going to show you a custom validator that can be used to better handle email validation. Most of this validation I found in a search but unfortunately I forgot to save the URL so I can’t link to the exact source. The following is the complete code for a custom email validator.

import {Control} from '@angular/common';

export class EmailValidator {
    static email(control: Control) {
        const emailRegexp = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;

        if (control.value !== "" && (control.value.length <= 5 || !emailRegexp.test(control.value))) {
            return { "email": true };
        }

        return null;
    }
}

Note that returning null means that validation passed.

Using a Custom Validator in a Model

First the custom validator needs to be imported.

import {EmailValidator} from './email.validator';

Now the validator can be used in the classes form builder.

this.contactForm = formBuilder.group({
    name: ["", Validators.compose([Validators.required, Validators.minLength(3)])],
    email: ["", Validators.compose([Validators.required, EmailValidator.email])]
});

Notices that the email control is now using Validators.compose which is used to apply multiple validations to a single control.

Using a Custom Validator in a View

Now the view just has to be changed to show the user that the reason for the failed validation is an invalid email address.

<div class="form-group">
    <label class="control-label">Email</label>
    <input type="email" ngControl="email" #email="ngForm" class="form-control">
    <div [hidden]="email.valid || email.pristine || !email.errors.required">Required</div>
    <div [hidden]="email.valid || email.pristine || !email.errors.email">Invalid address</div>
</div>

Note that the entry in errors will match the return value from the custom validator. I had issues trying to use the minimum length validator because I was trying to use minLength instead of minlength. If you are having trouble with validation message showing up that would be the first thing to check.

Wrapping Up

That covers the basics of model driven validation in Angular 2. Be on the look out for a post in the future that covers the same concepts but using a template driven approach. I also wanted to point out this post by Pascal Precht and this post by David Den Toom which helped me a lot in writing this post.

Angular 2 Model Driven Validation Read More »

Migration from ASP.NET Core RC1 to RC 2

ASP.NET Core release candidate 2 was released on May 16. The announcement can be found here. One reason for there being so much time between RC 1 and RC 2 is the dnvm, dnx and dnu tool set that ASP.NET Core had been built upon has been replaced by the .NET CLI. To replace the underpinnings of a system at the RC stage is a big under taking, but it was an important step to keep the a consistent set of tools across .NET’s cross-platform offerings.

Installation

With this release Microsoft added http://dot.net to better centralize acquisition of .NET. For ASP.NET Core use the download .NET Core or use this link to go directly to the install directions. If you are using Visual Studio you can get the MSI install from here.

After the installer is complete open a command prompt and run the command dotnet –version to verify version 1.0.0-preview1-002702 is installed.

Global.json

Only change here is a version update with the new value matching the following.

{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-preview1-002702"
  }
}

Project.json

The changes to this file were so extensive I found it easy to crate a new web application and copy the details out of the new project instead of tried to deal with editing my existing file. The only thing I kept from the original was my userSecretsId. If you do go this route make sure you change the schema (drop down at the top of the editor) to http://json.schemastore.org/project. The following is my resulting file.

{
  "userSecretsId": "replace with your secrets Id",

  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.0-rc2-3002702",
      "type": "platform"
    },
    "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final",
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-final",
    "Microsoft.Extensions.Logging.Debug": "1.0.0-rc2-final",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc2-final",
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    },
    "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
      "version": "1.0.0-preview1-final",
      "type": "build"
    }
  },

  "tools": {
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    },
    "Microsoft.Extensions.SecretManager.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": "portable-net45+win8+dnxcore50"
    },
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
      "version": "1.0.0-preview1-final",
      "imports": [
        "portable-net45+win8+dnxcore50",
        "portable-net45+win8"
      ]
    }
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "dnxcore50",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "gcServer": true
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ],
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

Namespace changes

The following are the namespace changes I hit. There is a pattern so if you hit any listed here it you should be able to make a good guess at what the new name is with AspNet going to AspNetCore and EntityFramework going to EntityFrameworkCore being the most common changes.

Old Namespace New Namespace
Microsoft.AspNet.Http.Authentication Microsoft.AspNetCore.Http.Authentication
Microsoft.AspNet.Authorization Microsoft.AspNetCore.Authorization
Microsoft.AspNet.Builder Microsoft.AspNetCore.Builder
Microsoft.AspNet.Identity Microsoft.AspNetCore.Identity
Microsoft.AspNet.Identity.EntityFramework Microsoft.AspNetCore.Identity.EntityFrameworkCore
Microsoft.AspNet.Hosting Microsoft.AspNetCore.Hosting
Microsoft.AspNet.Http Microsoft.AspNetCore.Http
Microsoft.AspNet.Http.Authentication Microsoft.AspNetCore.Http.Authentication
Microsoft.AspNet.Mvc Microsoft.AspNetCore.Mvc
Microsoft.AspNet.Mvc.TagHelpers Microsoft.AspNetCore.Mvc.TagHelpers
Microsoft.AspNet.Mvc.Rendering Microsoft.AspNetCore.Mvc.Rendering
Microsoft.Data.Entity Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Metadata.Internal
Microsoft.Data.Entity.Infrastructure Microsoft.EntityFrameworkCore.Infrastructure
Microsoft.Data.Entity.Metadata Microsoft.EntityFrameworkCore.Metadata
Microsoft.Data.Entity.Migrations Microsoft.EntityFrameworkCore.Migrations
System.Security.Claims Microsoft.AspNetCore.Identity

Application Entry Point

With the change to the CLI the Main function that was in the StartUp class is no longer sufficient. Using a new project as an example I removed Main from the StartUp and added a new Program class with that now contains the Main function for the application.

using System.IO;
using Microsoft.AspNetCore.Hosting;

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

            host.Run();
        }
    }
}

It is my understanding that all of the above was happening in the previous versions it has just now been made explicit.

StartUp Class

The StartUp had the second most changes after project.json. First as mention above the Main function was deleted. Next in the Startup function a call needs to be made to set the base path on the configuration builder. I missed the new SetBasePath(env.ContentRootPath) call at first and it caused an exception when builder.AddUserSecrets() was called.

Before:
var builder = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

After:
var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json")
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

Next in the ConfigureServices function the need to add entity framework and add SQL server is now gone. Also notice that the retrieval of the connection string has changed as well.

Before:
services.AddEntityFramework()
    .AddSqlServer()
    .AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]))
    .AddDbContext<ContactsDbContext>(options =>
        options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

After:
services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<ContactsDbContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

Finally in the Configure function the following should be removed as it is now handled via the UseIISIntegration() call in the application’s Main function.

app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());

Appsettings.json

The first change in appsettings.json is for the connection string settings mention above.

Before:
"Data": {
     "DefaultConnection": {
       "ConnectionString": "your connection string"
     }
}

After:
"ConnectionStrings": {
    "DefaultConnection": "your connection string"
}

Then the default logging level was changed from verbose to debug.

Before:
"Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Verbose",
      "System": "Information",
      "Microsoft": "Information"
    }
}

After:
"Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
}

Misc Changes in Various Controllers

The return values for HTTP statuses changed by dropping the Http prefix. The following are a few examples.

Old New
HttpBadRequest BadRequest
HttpNotFound NotFound
new HttpStatusCodeResult(StatusCodes.Status409Conflict) new StatusCodeResult(StatusCodes.Status409Conflict)

Getting access to the user ID form the current context now requires access to an instance of the UserManager class which needs to be injected via the constructor.

private readonly ContactsDbContext _context;
private readonly UserManager<ApplicationUser> _userManager;
  
public ContactsApiController(UserManager<ApplicationUser> userManager, 
                             ContactsDbContext context)
{
    _userManager = userManager;
    _context = context;
}

The following shows the difference in usage before and after the update.

Before:
return _context.Contacts.Where(c => c.UserId == User.GetUserId());

After:
return _context.Contacts.Where(c => c.UserId == _userManager.GetUserId(User));

More user ID related changes.

Before:
_userManager.FindByIdAsync(HttpContext.User.GetUserId())

After:
_userManager.GetUserAsync(HttpContext.User)

External principal is now just principal.

Before:
var email = info.ExternalPrincipal.FindFirstValue(ClaimTypes.Email);

After:
var email = info.Principal.FindFirstValue(ClaimTypes.Email);

Is signed in moved from user to the sign in manager.

Before:
User.IsSignedIn()

After:
_signInManager.IsSignedIn(User))

Validation Summary

The validation summary tag helper drop the ValidationSummary prefix.

Before:
<div asp-validation-summary="ValidationSummary.All" class="text-danger"></div>

After:
<div asp-validation-summary="All" class="text-danger"></div>

This of course applies to all usages of the validation summary tag helper not just the all case.

Entity Framework

The constructor of a child of DbContext should now accept options.

Before:
public ContactsDbContext()

After:
public ContactsDbContext(DbContextOptions<ContactsDbContext> options)
    : base(options)

There were changes to how tables get named with this version and if you try to run with out the following code entity framework will be unable to locate your tables. By adding the following to OnModelCreating your models will be force back to the naming scheme from RC1.

foreach (var entity in builder.Model.GetEntityTypes())
{
    entity.Relational().TableName = entity.DisplayName();
}

Other Resources

The above should get your project up and running. The changes I have covered here have been posted to my SPA sample application which can be found here and all the change I made are in this commit which should prove useful if I missed anything. During my migration a newly crated project proved to be my greatest resource.

Microsoft provided the following three migrations posts which are also very helpful.

There are also a number of people in the communitity that have also posted guides such as:

Migration from ASP.NET Core RC1 to RC 2 Read More »

Migration from Angular 2 Betas to RC

On May 2nd Angular 2 moved from the beta stage to the release candidate stage and is currently on RC 1. The move from beta to RC was a bit more involved than the moves between beta. This post is going to cover the changes I went through to get my SPA sample application migrated to RC 1.

Update package.json

With this release Angular 2 was split from a single dependency in to multiple. The other big change is a rename of from angular2  to @angular. The following is my updated dependencies section.

"dependencies": {
  "@angular/common": "2.0.0-rc.1",
  "@angular/compiler": "2.0.0-rc.1",
  "@angular/core": "2.0.0-rc.1",
  "@angular/http": "2.0.0-rc.1",
  "@angular/platform-browser": "2.0.0-rc.1",
  "@angular/platform-browser-dynamic": "2.0.0-rc.1",
  "@angular/router": "2.0.0-rc.1",
  "@angular/router-deprecated": "2.0.0-rc.1",
  "@angular/upgrade": "2.0.0-rc.1",

  "systemjs": "0.19.27",
  "es6-shim": "^0.35.0",
  "reflect-metadata": "^0.1.3",
  "rxjs": "5.0.0-beta.6",
  "zone.js": "^0.6.12"
}

After the above change make sure to run npm install in the root of the project from a command prompt. Not sure if it was just me, but the dependency auto restore in Visual Studio wouldn’t work for the @angular dependencies.

Update gulpfile.js

Due to the changes in the dependency structure my gulpfile had to be updated to copy the new files to the proper locations. I took the opportunity to move all of my dependency to a lib folder.

gulp.task("angular2:moveLibs", function () {
    return gulp.src([
            "node_modules/@angular/common/**/*",
            "node_modules/@angular/compiler/**/*",
            "node_modules/@angular/core/**/*",
            "node_modules/@angular/http/**/*",
            "node_modules/@angular/platform-browser/**/*",
            "node_modules/@angular/platform-browser-dynamic/**/*",
            "node_modules/@angular/router/**/*",
            "node_modules/@angular/router-deprecated/**/*",
            "node_modules/@angular/upgrade/**/*",
            "node_modules/systemjs/dist/system.src.js",
            "node_modules/systemjs/dist/system-polyfills.js",
            "node_modules/rxjs/**/*",
            "node_modules/es6-shim/es6-shim.min.js",
            "node_modules/zone.js/dist/zone.js",
            "node_modules/reflect-metadata/Reflect.js"
    ],
        { base: "node_modules" })
        .pipe(gulp.dest(paths.webroot + "Angular/lib"));

});

If you were using the previous version of my gulp take make sure to remove the old dependencies from the wwwroot/Angular/ folder.

Update Entry Point View

Again because of the dependency changes the entry point view for the Angular 2 application needed changes which is Angular2.cshtml in my project. A systemjs.config.js was added to handle the bulk of the configuration. The following is the full source for my entry point view.

<html>
  <head>
      <title>Angular 2 QuickStart</title>

      <script src="~/Angular/lib/es6-shim/es6-shim.min.js"></script>
      <script src="~/Angular/lib/zone.js/dist/zone.js"></script>
      <script src="~/Angular/lib/reflect-metadata/Reflect.js"></script>
      <script src="~/Angular/lib/systemjs/dist/system.src.js"></script>

      <script src="~/Angular/app/systemjs.config.js"></script>
      <script>
          System.import('app').catch(function(err){ console.error(err); });
      </script>
  </head>

  <body>
      <my-app>Loading...</my-app>
  </body>
</html>

Add system.config.js

This new file is where the configuration of systemjs happens. I found this setup in Dan Wahlin’s Angular2-JumpStart project which can be found here. The only real changes I made from Dan’s file was to adjust the map section to match my folder layout.

(function (global) {

    // map tells the System loader where to look for things
    var map = {
        'app': '../Angular/app', 
        'rxjs': '../Angular/lib/rxjs',
        '@angular': '../Angular/lib/@angular'
    };

    // packages tells the System loader how to load when no filename and/or no extension
    var packages = {
        'app': { main: 'boot.js', defaultExtension: 'js' },
        'rxjs': { defaultExtension: 'js' }
    };

    var packageNames = [
      '@angular/common',
      '@angular/compiler',
      '@angular/core',
      '@angular/http',
      '@angular/platform-browser',
      '@angular/platform-browser-dynamic',
      '@angular/router',
      '@angular/router-deprecated',
      '@angular/testing',
      '@angular/upgrade'
    ];

    // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
    packageNames.forEach(function (pkgName) {
        packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
    });

    var config = {
        map: map,
        packages: packages
    }

    // filterSystemConfig - index.html's chance to modify config before we register it.
    if (global.filterSystemConfig) { global.filterSystemConfig(config); }

    System.config(config);

})(this);

Update Component Imports

With the change in package names all imports that were using angular2 need to be changed to @angular. The following is an example of this from my app.component.ts file.

Before:
import {Component} from 'angular2/core';
import {OnInit} from 'angular2/core';
import {HTTP_PROVIDERS} from 'angular2/http';

After:
import {Component} from '@angular/core';
import {OnInit} from '@angular/core';
import {HTTP_PROVIDERS} from '@angular/http';

NgFor Change

There was also a slight syntax change around ngFor that changes the name declaration of the current item in the iteration of a loop. The following shows the before and after.

Before:
*ngFor="#contact of contacts"

After:
*ngFor="let contact of contacts"

Complete

With the above changes my application was run able again. The hardest part of the upgrade for me was getting systemjs configured properly. Hope your upgrade goes smooth and if not leave a comment with what issues you had.

Migration from Angular 2 Betas to RC Read More »

Aurelia Validation the Replacement Library

The post from last week on Aurelia Validation is now useless as this blog post from the Aurelia team states validation has been completely overhauled. This post is going to feel very similar to last weeks, but using the new validation library. The details on adding a main.js will match exactly from last weeks post, but is being included to make sure the examples in this post are complete.

Installation

Validation in Aurelia is provided using a plugin in which must be installed before being used. Make sure you have npm and jspm installed. For more information on getting up and running with Aurelia check out this post that will guide you through the process and links to a Github repo with matching code.

From the console execute this command jspm install aurelia-validatejs to download and install the files needed for validation.

In order to load plugins a named Aurelia-App is need to allow more control of the bootstrapping process. In Views/Home/Aurelia.cshtml make the following change.

Before:
<div aurelia-app>

After:
<div aurelia-app="main">

Now that this Aurelia application has been named “main” Aurelia will look for a matching main.js file and call its configure function during the bootstrapping process. Here is the main.js I am using. Note that the validation plugin in is being loaded. For my project main.js is located in wwwroot/Aurelia.

export function configure(aurelia) {
    aurelia.use
      .standardConfiguration()
      .developmentLogging()
      .pluginin('aurelia-validatejs');

    aurelia.start().then(() => aurelia.setRoot());
}

Usage

The first step in using validation is to add its import to the top of the class that will be using it.

import {ValidationEngine, Validator, required, email} from 'aurelia-validatejs';

Next setup the validation rules using decorators and inject validation via the constructor and set up the validation rules. The plugin also supports a fluent style of adding validation to property, but I ran into issues getting it working so I just stuck with decorators for this post.

static inject() { return [Validator]; }

@required 
Name = '';

@required 
@email 
Email = '';

constructor(validator) {
    this.reporter = ValidationEngine.getValidationReporter(this);
}

The above makes sure that Name is required and that email is required and conforms to the rule of what an email address. This is only a small sample of the built in validations provided by check out this page for a sample of the other provided validations.

Show Validation Failures in a View

The validation plugin in provides a way to display validation messages with the appropriate field. The following is a part of a view that contains name and email address that are bound to the properties from above.

<form>
    <div class="form-group">
        <label>Name</label>
        <input type="text" value.bind="Name & validate" class="form-control">
    </div>
    <div class="form-group">
        <label>Email</label>
        <input type="email" value.bind="Email & validate" class="form-control">
    </div>
</form>

By adding & validate as part of the value bind statement the plug in knows where the validation messages show be shown.

Warning

If you run into a “Cannot read property ‘bindingContext’ of null” when trying to implement the new validation plugin make sure your class constructor contains:

this.reporter = ValidationEngine.getValidationReporter(this);

From what I can tell this requirement will be temporary. This is an alpha release of the overhaul and has a few rough edges such as the binding context gotcha and the fluent API issues I mentioned above. With the track record of the Aurelia team I am sure the issues I hit will be resolved quickly.

Aurelia Validation the Replacement Library Read More »

Aurelia Validation

Update: this post is now out of date an updated version can be found here.

Client side validation is an important part of client side frameworks and can provide users with immediate feedback as well as check away to stop before posting data to the server. This post is going to look at validation with in Aurelia.

Installation

Validation in Aurelia is provided using a plugin in which must be installed before being used. Make sure you have npm and jspm installed. For more information on getting up and running with Aurelia check out this post that will guide you through the process and links to a Github repo with matching code.

From the console execute this command jspm install aurelia-validation to download and install the files needed for validation.

In order to load plugins a named Aurelia-App is need to allow more control of the bootstrapping process. In Views/Home/Aurelia.cshtml make the following change.

Before:
<div aurelia-app>

After:
<div aurelia-app="main">

Now that this Aurelia application has been named “main” Aurelia will look for a matching main.js file and call its configure function during the bootstrapping process. Here is the main.js I am using. Note that the validation plugin in is being loaded. For my project main.js is located in wwwroot/Aurelia.

export function configure(aurelia) {
    aurelia.use
      .standardConfiguration()
      .developmentLogging()
      .pluginin('aurelia-validation');

    aurelia.start().then(a => a.setRoot());
}

Usage

The first step in using validation is to add its import to the top of the class that will be using it.

import {Validation} from 'aurelia-validation';

Next the inject validation via the constructor and set up the validation rules.

static inject() { return [Validation]; }
constructor(validation) {
    this.Name = '';
    this.Email = '';
    this.validation = validation.on(this)
        .ensure('Name').isNotEmpty().hasLengthBetween(3, 50)
        .ensure('Email').isNotEmpty().isEmail();
}

The above makes sure that Name is required and has a length between 3 and 50 characters and that email is required and conforms to the rule of what an email address contain. This is only a small sample of the built in validations provided by check out this page for a demo of the other provided validations.

Show Validation Failures in a View

The validation plugin in provides a custom attribute that will loop all nested child elements and display validation messages with the appropriate field. The following is a part of a view that contains name and email address that are bound to the properties from above.

<form role="form" validate.bind="validation">
    <div class="form-group">
        <label>Name</label>
        <input type="text" value.bind="Name"placeholder="name" class="form-control">
    </div>
    <div class="form-group">
        <label>Email</label>
        <input type="email" value.bind="Email" placeholder="email" class="form-control">
    </div>
</form>

You can see that the validate custom attribute is bound to the validation property of the class defined above. Since the controls are in a form group the validation plugin is able to infer where bound field is show validation errors in the appropriate area. Check out this page for more details on visualization of validation errors. The default visualization is based on Twitter Bootstrap, but that can be changed the details of which can be found here.

Issues

Unfortunately I ran into some problems with trying to implement validation in a more complex situation dealing with an object that is replaced via binding. I doubt this is a problem with Aurelia. If anyone has any experience with validation on objects that are fully replaced via binding please let me know. Expect a blog post once I get my issue figured out.

Aurelia Validation Read More »

Execute Raw SQL in Entity Framework Core

From time to time your ORM is going to let you down in some way. No matter how good an ORM is there will always be some situations that the queries produced will not meet a performance requirement. Entity Framework Core will not be any different. This post is going to cover a couple of ways to execute raw SQL if the need arises.

Table Definition

The examples in this post are dealing with a Contacts table that contains columns for Id, Name, Address, City, State and Zip code. The following Entity Framework Core DbContext is defined for access to the Contacts table and is accessed via _context in all of the examples.

public sealed class ContactsDbContext : DbContext
{
    private static bool _created;
    public DbSet<Contact> Contacts { get; set; }

    public ContactsDbContext()
    {
        if (_created) return;
        Database.Migrate();
        _created = true;
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Contact>().HasKey(c => c.Id);
    }
}

DbSet FromSql

From any DbSet there is a FromSql function that will take raw SQL or a stored procedure that will be used instead of the SQL Entity Framework would have generated. The following example is using FromSql to load contacts based on the above DbContext and DbSet.

var results = _context.Contacts.FromSql("SELECT Id, Name Address, City, State, Zip " +
                                        "FROM Contacts " +
                                        "WHERE Name IN (@p0, @p1)",
                                        name1, name2);

FromSql takes a query followed by a list of parameters that should be used in the query’s execution. For example in the above @p0 maps to name1 and @p1 maps to name2. I recommend always using parameters instead of manually adding the filters to the SQL string in order to help prevent SQL injection attacks. Note that the @p followed by increasing numbers seems to be the only parameters that FromSql works with.

The great thing about this method is just like querying with via Entity Framework with LINQ execution is delayed and it returns an IQueryable so more filters can be added on as needed.

ADO.NET

Another options it to grab a connection from the DbContext using Database.GetDbConnection() and use ADO.NET to perform what ever operations are needed. Here is an example of connecting to the database and getting the name of the first contact. This is not a good example of a query that would need to be run this way, but provides a simple example of how a query would be executed.

using (var connection = _context.Database.GetDbConnection())
{
    connection.Open();

    using (var command = connection.CreateCommand())
    {
        command.CommandText = "SELECT COUNT(*) FROM Contacts";
        var result = command.ExecuteScalar().ToString();
    }
}

Since this is down to ADO.NET you can do pretty much anything that is needed including readers, adapters, data tables, etc. Hopefully the need for this option will be minimal, but it is important to know that it exists.

Execute Raw SQL in Entity Framework Core Read More »

Tool Spotlight – Add New File and Open Command Line Visual Studio Extentions

Tool Spotlight is a new type of post that I am trying out to bring attention to tools that I find useful and worth sharing. These entries will not be on any sort of schedule and will get posted anytime I come across a tool worth mentioning.

This post is going to cover two Visual Studio extensions that I find very helpful especially in the context of writing ASP.NET Core applications. Both of today’s extensions were written by Mads Kristensen.

 Add New File

The Add New File extension provides a simple way of adding new files without having to go through Visual Studio’s add new item dialog. Visual Studio’s dialog is great when I need it, but a lot of times I am adding a html or JavaScript file and just want a blank file and this extension provides a mechanism to do just that.

Lets look at the difference in the two dialogs. Here is Visual Studio’s dialog:

defaultAddNewFile

And here is what the add new file’s dialog looks like:

addNewFile

As you can see the extension’s dialog is much simpler. After the extension is install simply hit Shift+F2 to show the above dialog, enter a file name and click Add file to create a file in the current directory. Directories will also be crated as needed.

Open Command Line

The Open Command Line extension provides a way to open a console from within Visual Studio. The default console application is configurable with options from cmd and PowerShell to cmder and custom user defined applications. Opening the default console to the current directory of the selected item in Visual Studio’s solution explorer can be triggered using the Alt+Space shortcut. The extension also adds an Open Command Line option to the right click menu in solution explorer.

openCommandLineRightClick

Thoughts and Suggestions

Leave any thoughts on if this sort of post is helpful, your favorite tools or suggestions for future topics in the comments.

Tool Spotlight – Add New File and Open Command Line Visual Studio Extentions Read More »

Custom Pipes in Angular 2

I am working on a project that is using an ASP.NET Core web API to return JSON that is then used by Angular 2. The dates that needed to be formatted before being shown to the user which lead me to pipes.

Pipes

In Angular 2 pipes are away to apply some transformation on a field before its value is displayed to the user. Some common pipes are provided out of the box for things like numbers, dates and percentages.

For the following example created  is a property for the date a contact was added. To have created just display the month, date and year the date pipe will be used with the short date format.

{{contact.created | date: 'shortDate'}}

The above is standard Angular 2 binding  with an added pipe “|” followed by the name of the pipe which in this case is date. The built-in date pipe can take arguments for how to the date should be formatted. If the created date was today than the resulting output of the above binding would be 4/10/2016. For a full list of built-in formats see the Angular docs.

The Problem

I added the date pipe to the fields that needed formatting and ran the app. Instead of the formatted date I was expecting I got a partially rendered page. A quick peek in Chrome’s dev tools showed the following exception.

EXCEPTION: Invalid argument ‘2016-04-10T08:00:00’ for pipe ‘DatePipe’ in [{{contact.created | date: ‘shortDate’}}

Turns out that the date pipe only works if the value it is processing is a number or a date. I found this out by looking at the code for the date pipe which can be found here. My created property came from JSON which doesn’t have a way to denote something as a date. This means the created property is actually a string instead of a date..

Solution 1 – Convert to a date

One way to fix this issue is to use the string representation of the date to create a new date and assign it over the top of the existing property. For example:

contact.created = new Date(contact.created);

After the above is applied to all the dates that need formatted Angular’s date pipe can be used with no problems.

Solution 2 – Custom pipe

I decided to try writing a custom pipe that would take a string that should be a date and format it if it is actually date using Angular’s date pipe.  The following is the resulting pipe.

import {Pipe, PipeTransform} from 'angular2/core';
import {DatePipe} from 'angular2/common';

@Pipe({ name: 'dateString' })
export class DateString implements PipeTransform {
    transform(value: string, args: any[]): string {
        var parsedDate = Date.parse(value);
        if (isNaN(parsedDate)) {
            return "";
        }
        else {
            return new DatePipe().transform(new Date(parsedDate), args);
        }
    }
}

First Pipe and PipeTransform are imported. The class must be decorated with @Pipe which is also used to give the pipe its name. The class must also implement PipeTransform which defines a transform function.

The transform function is where all the work happens. It takes a value and formatting arguments and return the value that should be displayed. In my case the value is parsed to a date which returns the number of milliseconds since January 1, 1970 00:00:00 UTC or not a number if parsing fails for some reason. For the not a number result an empty string will be return and displayed to the user.

In the case the date is value then a new instance of Angular’s date pipe is created it handles formatting using the new date value which is then return and displayed for the user. In order to use Angular’s date pipe inside my custom pipe it needed to be imported as well.

Custom Pipe Usage

To use a custom pipe it must be imported by the view model class of the view that needs formatted.

import { DateString } from './dateString.pipe';

Then it must be added to the component decorator.

@Component({
    selector: 'viewContacts',
    templateUrl: 'viewContacts.component.html',
    pipes: [DateString]
})

The view will now be able to use the pipe. The syntax is the same as built-in pipes just with the name provided in the pipe decorator which is dateString in this example.

{{contact.created | dateString: 'shortDate'}}

Suggestions

The above are two of the solutions I came up with when I had problems with Angular’s built in date pipe. They are by no means the only options. If you have a suggestion on a better way to handle dates coming from JSON please leave a comment.

Also note that there is an issue logged on the Angular repo to support strings in the built in date pipe which can be found here.

Custom Pipes in Angular 2 Read More »