Entity Framework Core

ASP.NET Core Conversion to csproj with Visual Studio 2017 and update to 1.1.1

On March 7th Visual Studio 2017 was released bring the ASP.NET Core tools preview. ASP.NET Core 1.1.1 was also released. This post is going to cover converting the project from my MailGun post from being project.json based to csproj as well as migrating from the project from ASP.NET Core 1.0.2 to 1.1.1. Here is the project as it stood before I made any changes.

Visual Studio 2017

The first step is to get a version of Visual Studio 2017 (VS 2017) installed. The download page can be found here. Make sure to grab the community edition if you are looking for a free fully-featured IDE option. Check out this blog post from Microsoft on the many new features Visual Studio 2017 brings.

The installer for VS 2017 has changed a lot from previous versions. The way it works now is you select the workload you use and it only installs the bit it has to to keep the size of install down. The following is a screen shot from my install. I have a lot more workloads checked that is needed for just an ASP.NET Core application. At a minimum make sure the “ASP.NET and web development” workload gets installed. If you are interested in cross-platform development scroll to the bottom and also check “.NET Core cross-platform development”.

Project conversion

When you open the solution in VS 2017 it will prompt you to do a one-way upgrade.

After the conversion is complete a migration report will open. Below is mine. I had no issues, but if there were any this report should give you some idea of how they should be addressed.

As part of the conversion process, the following file changes happened.

Deleted:
global.json
ASP.NET-Core-Email.xproj
project.json

Added:
ASP.NET-Core-Email.csproj

That is all there is to the conversion. The tooling takes care of it all and your project should keep work just as before. The sample project post conversion can be found here.

Migration from 1.0.x to 1.1.1

The migration is almost as simple as the project conversion. In the solution explorer right click on the project to be migrated and select Properties.

Find the Target framework selection and select .NETCoreApp 1.1. Then save your solution.

Next, open the NuGet Package Manager. It can be by right click on the project and selecting Manage NuGet Packages or from the Tools > NuGet Package Manager > Manage NuGet Packages for Solution.

Select the Updates tab and update all the related packages to 1.1.1 and click the Update button.

If you want a specific list of all the package changes check out the associated commit.

The only other change needed is in the constructor of the Startup class.

Before:
builder.AddUserSecrets();

After:
builder.AddUserSecrets<Startup>();

Wrapping up

After all the changes above your solution will be on the latest released bits. Having been following releases since beta 4 I can tell you this is one of the easiest migration so far. I may be partial, but .NET and Microsoft seem to be getting better and better over the last couple of years.

I am going to leave you with a few related links.

ASP.NET Core 1.1.1 Release Notes
Announcing New ASP.NET Core and Web Dev Feature in VS 2017
Project File Tools – Extension for IntelliSense in csproj
Razor Language Services – Extension for tag helper Intellisense

Migration from ASP.NET Core 1.0.x to 1.1

UPDATE: For a guide dealing with the conversion to csproj/Visual Studio 2017 check out this post.

On November 16th .NET Core 1.1 was released including ASP.NET Core 1.1 and Entity Framework 1.1. Each of the links contain the details of what was including in the 1.1 release. Unlike some of the previous migrations this is pretty simple.

I will be using my normal ASP.NET Basics solution for this upgrade. The examples will be out of the Contacts project. This post is coming out of order so the repo that goes with this post will contain some items not covered in posts yet. The starting point of the repo can be found here.

Installation

Make sure you already have Visual Studio 2015 Update 3 installed with .NET Core 1.0.1 tools Preview 2 installed. If not use the previous links to install the needed versions. Next head over to the download page for .NET Core and under All downloads and select Current and SDK and select the download for your OS.

downloaddotnet

Another option is to install Visual Studio 2017 RC which can be found here.

Project.json

Project.json is the file that contains all the versions of assembles used by the application. A couple of items need to edited by hand and the rest can be updated using NuGet UI or you can change them all by hand if you like.

First the by hand items. The platform version needs to be updated to 1.1.

Before:
"Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    }

After:
"Microsoft.NETCore.App": {
      "version": "1.1.0",
      "type": "platform"
    }

The second by hand item is the net core app version in the frameworks section.

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

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

Here is the resulting dependencies and tools sections.

"dependencies": {
  "Microsoft.NETCore.App": {
    "version": "1.1.0",
    "type": "platform"
  },
  "Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
  "Microsoft.AspNetCore.Diagnostics": "1.1.0",
  "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.1.0",
  "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.1.0",
  "Microsoft.AspNetCore.Mvc": "1.1.0",
  "Microsoft.AspNetCore.Razor.Tools": {
    "version": "1.1.0-preview4-final",
    "type": "build"
  },
  "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
  "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
  "Microsoft.AspNetCore.StaticFiles": "1.1.0",
  "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
  "Microsoft.EntityFrameworkCore.SqlServer.Design": {
    "version": "1.1.0",
    "type": "build"
  },
  "Microsoft.EntityFrameworkCore.Tools": {
    "version": "1.0.0-preview3-final",
    "type": "build"
  },
  "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
  "Microsoft.Extensions.Configuration.Json": "1.1.0",
  "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
  "Microsoft.Extensions.Logging": "1.1.0",
  "Microsoft.Extensions.Logging.Console": "1.1.0",
  "Microsoft.Extensions.Logging.Debug": "1.1.0",
  "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
  "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0",
  "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
    "version": "1.1.0-preview4-final",
    "type": "build"
  },
  "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
    "version": "1.1.0-preview4-final",
    "type": "build"
  },
  "BundlerMinifier.Core": "2.2.301"
},

"tools": {
  "BundlerMinifier.Core": "2.2.301",
  "Microsoft.AspNetCore.Razor.Tools": "1.1.0-preview4-final",
  "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.1.0-preview4-final",
  "Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final",
  "Microsoft.Extensions.SecretManager.Tools": "1.1.0-preview4-final",
  "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
    "version": "1.1.0-preview4-final",
    "imports": [
      "portable-net45+win8"
    ]
  }
}

Make note that using the NuGet UI will update the dependencies but not the tools section. For some reason the tools section doesn’t seem to have intellisense so I ended up searching the NuGet site to find the new versions. If you do end up changing the tooling version I recommend doing a dotnet restore in the project directory from the command prompt to ensure the proper versions get downloaded.

Wrapping up

As I said this was a really pain less migration. Make sure you check out the release pages ( .NET Core 1.1ASP.NET Core 1.1 and Entity Framework 1.1) for the details on what has changed. For example ASP.NET Core has gotten significant performance increases with this release as well as URL Rewriting Middleware and Response Caching Middleware.

It has been less than six months since the initial release of ASP.NET Core until the 1.1 release which a huge increase in the pace of releases compared regular ASP.NET. From what I have see this is a pace the team will continue. Check out the roadmap for a preview of things coming in 1.2.

The code in its final state can be found here.

ASP.NET Core Basics: API Controller

This week’s post is going to cover the creation of an API controller. The starting point for this post is based on this post from last week and the starting state of the code can be found here.

Scaffolding

Using the same Contact model class from last week’s post Entity Framework Core’s scaffolding can be used to generate an API controller for us with all the read and write actions already written. To begin in the Solution Explorer window right click on the Controllers folder and select Add > New Scaffolded Item.

AddNewScaffoldedItemMenu

On the Add Scaffold dialog select API Controller with actions, using Entity Framework. This option will create an API controller with read and write actions based on a model.

AddScaffoldApi

On the Add Controller dialog for the model class select the Contact class, for the data context class select the existing ContactsContext. Finally enter the controller name you would like to use. I am using ContactsApiController since the MVC controller from last week’s post is already named ContactsController.

AddApiControllerDialog

Click add and the scaffolding process will create a ContactsApiController in the Controllers folder. With that the project now contains a fully functional contacts API that will handle gets, puts, posts and deletes with zero code changes.

Test with Postman

Postman is a great tool that I always use when developing an API that allows me to exercise all the functions of the API before any clients have been built. I know you can do some of the same things using a browser, but Postman was built for this type of usage and it shows. Postman is free and you can grab it from here as a Chrome app or they have app versions available here.

After installing the application and running it you will see something like the following.

PostmanBlank

It is best to have some data available for testing so in the case of this application I recommend using the UI added in last weeks post to add a couple of contacts.

Now that some data is available it is time to test the GetContact function on the ContactsApiController. If you run the application it should open in a browser from which you can copy the URL, or right click on the project select properties then on the Debug tab copy the URL from the App URL field.

ProjectProperties

Paste the base URL in the URL box in Postman and then add on the route for the endpoint you are wanting to test. In this case I want to test the the GetContact function on the ContactsApiController so I will be using the a URL of http://localhost:13322/api/contactsapi. Next make sure contact application is running and then click the send button in Postman. The application should respond and the results of the API call will be displayed on the body tab of Postman.

PostmanGetContacts

Postman can be used to try out pretty much all aspects of the API that an application has. For example if you wanted to test out the PostContact then in Postman click the down arrow next to Get and select Post. Next select the upper body tab (in the request area) and the click the raw radio button. Then to the right of the radio buttons hit the down arrow and select JSON (application/json) and then it the large text box you can enter the JSON that will be sent to the server when you click the send button. The following is an example of a post request.

PostmanPostContact

Wrapping Up

This application now has a fully functional API and we have covered how test it using Postman.

The next step would be to create some sort of client to actually utilized the API such as an Aurelia or Angular 2 application.

The code for this post can be found here.

ASP.NET Core Basics: MVC Controller with Entity Framework Core

Last week’s post covered the installation and creation of a new project in ASP.NET Core. This week I will be expanding that existing project to create a basic contact list which will use Entity Framework Core and its scaffolding capabilities to generate the needed files from a model class. This code from last week is being used as a starting point for this post.

Add a Model

To start off I need a class to represent the information for a single contact. In the default setup the proper place to store this type of class is in the Models folder. To add a new class from the Solution Explorer window right click on the Models folder and select Add > Class menu option.

AddClassMenu

This menu choice will bring up the Add New Item dialog defaulted to adding a new class. Enter the name as Contact.cs and click Add.

AddNewItemDialogContact

The following is my resulting Contact after adding the properties of a contact that this application is going to use.

namespace Contacts.Models
{
    public class Contact
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string PostalCode { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
    }
}

Scaffolding

Now that the application knows what a Contact looks like we can take advantage of a feature of Entity Framework Core called scaffolding. Scaffolding can be sued to create a number of different setups based on a model, but in this case it I am using it to generate a MVC Controller with views, using Entity Framework which will result in a controller, DbContext and associated MVC razor views being created.

In the Solution Explorer window right click on the Controllers folder and select Add > New Scaffolded Item.

AddNewScaffoldedItemMenu

On the Add Scaffold dialog select MVC Controller with views, using Entity Framework. This is the only option that will create views. Now click the Add button.

AddScaffoldDialog

The Add Controller dialog will be shown next. First select the model that should be the base of the scaffolding operation which is the Contact class for this project. For the data context class option I used the plus (+) button to add a new one since this project doesn’t have an existing data context that I want to use.

AddControllerDialog

After clicking add and letting the process finish the Controllers folder will now contain a ContactsController and in the Models folder there will be ContactsContext. I always move the newly created context out of the Models folder and into the Data folder to match the location used for the ApplicationDbContext.

Entity Framework Migration

Now that the application has a contact model and DbContext it is time to create an entity framework migration which is the mechanism entity framework uses to create and/or migrate a database to match the changes made in the models of an application. Migrations can be added within Visual Studio via the Package Manager Console or from a command prompt using the .NET CLI. I am going to walk through both, but keep in mind you only need to use one.

Package Manager Console

To open the Package Manager Console use the View > Other Windows > Package Manager Console menu. Which show a window that looks like the following.

PackageManagerConsole

To add a migration use run the Add-Migration Init-Contacts -Context ContactsContext command. The Package Manager Console is using powershell so Add-Migration is a command that take a parameter that is the name of the migration which is Init-Contacts in this case. -Context ContactsContext is required in this application because it contains more than one DbContext and the command has to know which DbContext it is working with.

.NET CLI

Open a command prompt and navigate to your project’s directory and then run the dotnet ef migrations add Init-Contacts –context ContactsContext command. This is does exactly the same thing as the Package Manager Console above with just slightly different syntax.

Regardless of which version is used you will see a new Migrations folder added to the root of the project that contains a snapshot of the models referenced by the relevant DbContext as well as a migration file named by using a time stamp plus the migration name.

Automatic Database Migration

In the early stages of a project (or always if it meets your need) it is nice to automatically apply migrations instead of having to do so manually using the package manager console or the .NET CLI. One way to accomplish this is to add a static flag to the constructor of the DbContext in question and if that flag is false then use Database.Migrate() to apply any migrations that the database is missing. Here is an example using my ContatsContext class with the flag named _created.

public sealed class ContactsContext : DbContext
{
    private static bool _created;
    public DbSet<Contact> Contact { get; set; }
    public ContactsContext(DbContextOptions<ContactsContext> options)
        : base(options)
    {
        if (_created) return;
        Database.Migrate();
        _created = true;
    }
}

Add Navigation

At this point you could type in a URL that would take you to the index action of the new ContactsController, but it would be much more useful to add a link to the sites navigation bar to provide an easy way to access the new functionality. The code for the navigation bar can be found in _Layout.cshtml which is located in the Views > Shared folder.

The navigation bar is defined using an unordered list with a class of “nav navbar-nav”. Add a new link to the unorderd list labeled Contact List. This new link needs to point to the index action of ContactsController. ASP.NET Core provides some tag helpers to assist in building links to controller actions. Using the asp-controller and specify “Contacts” as the controller which will resolve to the ContactsController and then use asp-action set to “Index” to point to the index action.

<ul class="nav navbar-nav">
    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
    <li><a asp-area="" asp-controller="Contacts" asp-action="Index">Contact List</a></li>
    <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
    <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>

Wrapping Up

Now when the application is run there will be a link for Contact List at the top that will trigger actions in the new controller and backing database table.

Next week I play to take this same project and add a web API end point to it and show how that end point can be verified using Postman.

The code that goes with the post can be found here.

ASP.NET Core Basics: Project Creation

With ASP.NET Core released it seems like a good time to do a series of posts on the basics of this new platform starting with getting a new project up and running.  In this post I am going to walk through installation of ASP.NET Core and then move to project creation. This project will end up being a basic contact list application although there will not be much specific to that end goal in this post.

Installation

All the software needed for this post can be found at http://dot.net. I will be using Visual Studio 2015 in my examples and if you don’t have it installed already it can be downloaded using the Download Visual Studio 2015 button on the right of the above page or by clicking here. If you already have Visual Studio 2015 installed please ensure you have installed Update 3.

The next bit of software you will need is found by clicking the Download .NET Core 1.0 or clicking here. This page has a good write up getting started with .NET Core, but all you need is the install for .NET Core 1.0 for Visual Studio which can be found here.

To verify that .NET Core is installed open a command prompt and run dotnet –version which will print the current version of .NET Core you have installed. As of this writing this my version is 1.0.0-preview2-003121. While .NET Core its self has been officially released the tooling is still in preview which is why the version contains preview2-003121.

Project Creation

Launch Visual Studio and from the File > New menu select Project…

NewProject

This will load the New Project dialog. On the left side under Templates > Visual C# > .NET Core select ASP.NET Core Web Application (.Net Core) or you can use the search box in the upper right of the screen to search for “ASP.NET Core Web Application (.Net Core)”.

NewProjectDialogContacts

Next on the New ASP.NET Core Web Application dialog select Web Application. This option creates an application with example MVC Views (razor) and an example controller. Notice the note that this template can be used for RESTful HTTP services as well. Next click the Change Authentication button.

NewAspNetCoreWebApplication

For this example I am going to use Individual User Accounts. This option adds UI, models, controllers, etc. to allow registration and management of user accounts. Since the option needs a database to store account information it include Entity Framework Core. Click OK on the Change Authentication dialog and then click ON new web application dialog.

ChangeAuthentication

Project Overview

After the creation process is finished got to the Solution Explorer window and you will see a set up similar to the following.

SolutionExplorer

I am going to point out a few of the files and folder that are part of a newly created application. Fist is wwwroot which is where static files will be severed as long you are using the static files middleware.  This is where images, CSS and JavaScript should go.

appsettings.json is where you will find connection strings and logging settings by default. Your own settings can be added here as well.

project.json is where you will find all your project’s dependencies (using the NuGet UI or Package Manager console both write to this file), tools, frameworks, build options, runtime options, publish options and scripts are all defined. Thankfully this file has good support for intellisense if you decide to edit it manually. This file covers a lot, but for this introduction I am going to avoid digging into the specifics.

Startup.cs is the last file I want to call out. Its generated contents are fine for this example project, but it has a couple of functions you should be aware of. First ASP.NET Core comes with dependency injection built in and the ConfigureServices function is where items are registered with the built in container. The second function is Configure and this is the function where the HTTP request pipeline for your application is configured using various middleware.

Wrapping Up

At this point you have a web application that can be run (press F5 to run with the debugger attached or Ctrl + F5 to run without the debugger). With no code changes you now have a web application that has basic navigation, controllers, views and authentication.

With this series of post things are being kept intentionally short and focused on one or two main topics. Next week will build on this basic project by adding in the ability to manage contacts, using a new controller and associated razor view which will be persisted to a database using Entity Framework Core.

The code that goes with this post can be found in this GitHub repository.

 

Migration from ASP.NET Core RC2 to RTM

On June 27th .NET Core 1.0 RTM was released which include ASP.NET Core 1.0 and Entity Framework Core 1.0. The links are to the official Microsoft announcement blogs.

Installation

Install instructions can be found at http://dot.net using the Download .NET Core button in the bottom center of the page or use this link to go directly to the install directions. If you are using Visual Studio 2015 then update 3 must be installed before installing .NET Core for Visual Studio which includes the RTM bits plus preview 2 of the related tooling.

After both installers are complete open a command prompt and run the command dotnet –version and verify the version is 1.0.0-preview2-003121.

Global.json

Update the version in the sdk section.

{
  "projects": [ "src", "test" ],
  "sdk": {
    "version": "1.0.0-preview2-003121"
  }
}

Project.json

The following table can be used to find and replace a lot of the changes in this file.

RC2 RTM
1.0.0-rc2-3002702 1.0.0
1.0.0-rc2-final 1.0.0

The run time option for server GC was moved.

Before:
"runtimeOptions": {
  "gcServer": true
}

After:
"runtimeOptions": {
  "configProperties": {
    "System.GC.Server": true
  }
}

A new option is now included in the publish options for “Areas/**/Views”.

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

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

Finally in the scripts section if you are not using NPM and Gulp then the following change should be made. It is my understanding the choice to remove NPM and Gulp by default was to speed up restores.

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

After:
"scripts": {
  "prepublish": [ "bower install", "dotnet bundle" ],
  "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}

Here is the full file for reference with NPM left in.

{
  "userSecretsId": "YourSecretsId",

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

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

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

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

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "Views",
      "Areas/**/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%" ]
  }
}

Breaking Changes

A list of breaking changes for this release can be found here. The only one I hit was this issue which changes the JSON serializes to use camel case names by default. To restore the previous behavior making the following change in the ConfigureServices function of the Startup class.

Before:
services.AddMvc();

After:
services.AddMvc()
        .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

Congratulations

Congratulations to .NET Core teams for hitting RTM! I know there has been some negative things said about the amount of churn in the RC phase of the project, but based on what I feel they made the right choice for the future of the platform. If you don’t already I highly recommend watching the ASP.NET Community Stand-up where you can see a lot of these issues discussed by the team.

In the next few of weeks the team should be releasing a road map of what they are going to be working on next such as SignalR.

.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.

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:

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.