Saturday, June 30, 2018

In this post I shall describe the steps you need to follow if you want to add more data fields to the standard users & roles database table and seed both users and roles data. The approach being followed is code first development with Entity Framework Core. In order to proceed with this tutorial you need to have the following prerequisites:

You are using Visual Studio 2017 running under the Windows 10 operating system

You have installed ASP.NET 2.1 Core

Getting Started

In Visual Studio 2017, start a new ASP.NET Core 2.1 application by clicking on File >> New >> Project

Select ASP.NET Core Web Application and name your project with a name like IdentityCore.

Click on OK. Run the application by hitting Ctrl + F5 on your keyboard. Click on the Register link on the top-right side of your keyboard to add a new user.

When you click on the Register button, you may receive a message that looks like this:

Do not be alarmed. The message simple reminds you that the Entity Framework migrations have not been applied yet. Simple click on the blue "Apply Migrations" button then refresh the page in your browser. The home page will display as shown below:

Click on Logout in the top-right corner.

Suppose we want to capture more data about the user, in addition to email and password. Let us assume we want to extend user data with the following properties:

FirstName
LastName
Street
City
Province
PostalCode

An easy way to do this is to create a new class that extends IdentityUser and adds the above properties. In the Models folder, add a new class named ApplicationUser and add to it the following class code:

We may also wish to extend the standard roles table with these properties:

Description
CreatedDate

Just like we did with users, we will also create another class for roles that inherits from IdentityRole. In the Models folder, create a new class named ApplicationRole and add to it the following class code:

Edit Data/ApplicationDbContext.cs file and get ApplicationDbContext to inherit from IdentityDbContext<ApplicationUser, ApplicationRole, string>. The ApplicationDbContext class code should look like this:

We will use the magic of dependency injection to make available to us the ApplicationDbContext, RoleManager and UserManager objects in the Configure() method in Startup.cs. Change the signature of the Configure() method by adding additional arguments (UserManager & RoleManager) so that it looks like this:

Note that in the Data/Migrations folder there are Entity Framework Code First migrations files that were added by the initial Visual Studio project template.

Since we changed the model for both users and roles, we need to add another migration and subsequently update the database. Therefore, execute the following commands from inside the Package Manager Console (Tools >> Nuget Package Manager >> Package Manager Console):

At this stage the tables are created, however data is not yet seeded. Let us run our application so that the sample roles and users get seeded. Hit CTRL + F5 on your keyboard. When the application starts, Logout if you are already logged in.

To prove that user and role data have been successfully seeded, login with one of the below credentials that were previously seeded:

The next task we need to accomplish is to modify the registration page so that the application can capture extended data such as First Name, Last Name, Street, City, Province, Postal Code and Country. ASP.NET Core 2.1 (and later) provide ASP.NET Core Identity as a Razor Class Library. This means that the registration UI is baked into the assemblies and is surfaced with the .AddDefaultUI() option with the services.AddIdentity() command in the ConfigureServices() method in Startup.cs.

Since we need to modify the registration controller and view, we instruct the scaffolder to generate the code used for registration. To do this, right-click on the project node in the Solution Explorer pane then: Add >> New Scaffolded Item:

On the next Add Scaffold dialog, click on Identity on the left side, highlight Identity in the middle pane then click on the Add button.

On the Add Identity dialog, enable the "Override all files" checkbox, select the ApplicationDbContext class then click on the Add button.

Many Razor view pages will be generated for you under folder Areas/Identity/Pages/Account.

Edit the code-behind file Areas\Itentity\Pages\Account\Register.cshtml.cs. Add the following properties to the InputModel class:

Run the web application and click on the Register button on the top-right side.

When you click on the register button all the user data is saved in the database. You can verify that data has indeed been saved by viewing data in the AspNetUsers database table using "SQL Server Object Explorer":

We have succeeded in seeding user and role data and subsequently updating the registration page so that additional user data is captured. Thanks for coming this far in the tutorial.

Tuesday, June 26, 2018

This post introduces the reader to developing an ASP.NET Core 2.1 application that uses the Code 1'st approach with SQL Server. Before you proceed with this tutorial, make sure that the following pre-requisites are met:

You are using the Windows 10 Operating System

You have Visual Studio 2017 installed on your computer

ASP.NET Core 2.1 is installed on your computer

The objective is to model NHL (National Hockey League) teams and players as shown below:

Team

TeamName
City
Province
Country

Player

PlayerId
FirstName
LastName
Position

The Visual Studio Project

Start your Visual Studio 2017

File >> New >> Project...

Select ASP.NET Core Web Application

Give your project a name (like MvcEfCore)

On the next dialog, after you click on OK, choose ASP.NET Core 2.1 and Web Application (Model-View-Controller). Click on the Change Authentication button and select Individual User Accounts.

Click on OK.

Let us add two classes (Team & Player) that represent the entities that were mentioned beforehand. Create two class files in the Models folder: Team.cs & Player.cs. Replace the class code with the following:

The above code ensures that we can use the NhlContext class in dependency injection and that it uses the DefaultConnection connection string in appsettings.json.

Open appsettings.json for editing and change the database name so that it is simply NHL and not a long non-sense name. The appropriate connection string setting in appsettings.json will look like this:

Developers prefer having sample data when building data driven applications. Therefore we will create some dummy data to ensure that our application behaves as expected. Create a class file named DummyData in the Data directory and add to it the following code:

Test Application

We are now ready to run the application. Hit Ctrl+F5 on your keyboard. The application will run and will look like this:

Of course there is no sight of the data that was created. To view the sample data in Visual Studio, click on View >> SQL Server Object Explorer. This opens up a pane in Visual Studio. Expand nodes database server >> Databases >> NHL >> Tables.

Right-click on dbo.Teams then select View Data. You should see Teams sample data in the database.

Likewise, view Players sample data.

Notice that the last column in the Players entity is a foreign key into the Teams entity.

Let us now scaffold the MVC controllers for both of these entities. Back in Solution Explorer, right-click on Controllers then select Add >> Controller. Select "MVC Controller with views, using Entity Framework".

Choose Team for Model class and NhlContext for Data context class.

When you click on the Add button, the controller for Teams is scaffold-ed for you. This includes the action methods for displaying, creating, editing and deleting data.

Just like you created a controller for the Team table, do the same for the Player table.

To view the output of the controllers created, you can run the application by hitting Ctrl + F5 then add either /teams or /players to view the Teams or Players controllers respectively.

The Teams controller

The Players controller

There is one thing we need to fix in the Teams index view. Since team name is a primary key it does not display in the tabls. The team-name is important to us so we need to modify Views/Teams/Index.cshtml. Open the file in Visual Studio and add the following HTML code as the first column title in the table:

<th>
@Html.DisplayNameFor(model => model.TeamName)
</th>

Also, add the following column data to the table with this HTML code:

<td>
@Html.DisplayFor(modelItem => item.TeamName)
</td>

When you run the application with /teams added to the address line, you should see team names.

Let us add menu items on the home page of our application for Team & Player so we do not have to always access these controllers by typing into the address line. To do this, edit Views/Shared/_Layout.cshtml. Add the following HTML code right before the closing </ul> tag: