Category Archives: EntityFramework

[EN] How to populate database in ASP.NET Core Web Api

When we create our app it’s good to have some data in a database at some point, for example test user accounts or other values if we want to test something. How to populate database at the start of application if the database is empty?

First we need to create new class in our project. Let’s see how to do it on example.

I want to seed the database with test user with admin role, because I want to test loging functionality.

Here’s my class with Seed method.

What it does, it just checks if user „TestAdminUser” and role „Admin” exist in the database. If not it adds them and assigns role and claim to the user. If you are wondering what is User class, I have user class defined which is derived from IdentityUser class (Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUser), so it’s IdentityUser class with additional properties.

ELPIdentityInitializer class is not complicated, but we can add here more data. The question is how to load this data and when? As you probably guess, the good place is Startup class and Configure method, because it will be called only once at the start of application. To achieve our goal we need to add another parameter to this method. In my case it will be parameter of type ELPIdentityInitializer. In the body of Configure method, at the end (after UseMvc() method call) we need to execute Seed method from our initializer. This method is awaitable, so we can just wait for completion, because we don’t want to change Configure method to be asynchronous.

Additionally we need to register our initializer class in the service collection, because without it we will see an error while resolving class. To do it let’s add this line of code to the ConfigureServices method in Startup class.

I used AddTransient method here. It means service is created each time it is requested, but it’s not important here. Our service is requested only once at the beginning. BTW Transient lifetime works best for lightweight and stateless services.

After these few steps we should see result of our work which is populated database, in this case Users table.

1

[EN] Cookie authentication in ASP.NET Core Web Api

This time I want to focus on user authentication. In APIs we can use different methods for user authentication like:

-cookie Authentication

-basic Authentication (not recommended, slow and insecure)

-token Authentication

In this post I want to show you how to implement cookie authentication in ASP.NET Core Web API.

First make sure you have installed Microsoft.AspNetCore.Identity.EntityFrameworkCore NuGet package in your project. Then let’s modify model a little bit.

Create User class derived from IdentityUser.

Next modify Context class. Our Context should be derived from IdentityDbContext<User> class. If your Context is derived from DbContext class, you need to change it. IdentityContext helps us to create all tables needed for user like Roles, Claims, Tokens, etc.

After these modifications, add another migration via Package Manager Console (type Add-Migration migrationName) and update database by Update-Database command. If you don’t know how to perform code first migrations take a look at one of my previous post.

If we have database ready, we can focus on our API project. In Startup.cs class in ConfigureServices method we need to add identity to services by adding this line of code:

where ELPContext is your app context and User is user class derived from IdentityUser.

That’s not all, we need to add more code, to specify how Identity should work. There’s a small problem with ASP.NET Core WebApi, when you call method that needs authorization you can get 404 Not Found Error instead of 401 Unauthorized. It’s because of default redirection to Account/Login page which can be helpful in ASP.NET MVC project but not in Web API. To handle it we need to set up application cookie events. Events allow us to override things that the IdentitySystem does. Add this code after AddItentity method call.

In the Configure method in Startup class we need to add another line of code before calling app.UseMvc() method:

We have configured our project, so let’s implement controller with register and login methods. I prefer to avoid logic in Controllers and use only services, so first we need to create UserService. This is my UserService for now.

I use UserManager and SigninManager that come from Microsoft.AspNetCore.Identiy namespace. These managers do a lot for us.

When we have service it’s time to use it in Controller.

We have two methods Register and SignIn. It’s time to test it. Hit F5, start your API and open Postman (If you don’t know what is Postman go to my previous post where I mentioned about it).

In Postman pick Post method call, add body which is raw JSON and hit Send. You should see success and status 200 like on image below.

1

To test Signin method, repeat above steps. You can see in the result in the Cookies tab there’s  cookie provided by ASpNetCore.Identity.Applcation. It contains information about the user. If you close the Postman or browser you have to re-authenticate. The cookie passed back and forth is the thing that going to know what the user is.

2

Next time I will show you how to implement Token based authentication which is recommended method of authentication 😉

If you want to take a look at the source code it is available in my Github repo.

[EN] Entity Framework Core – Code First migrations

In this post I want to show you how to create new database using Entity Framework Core – Code First migrations approach.

codefirst

I have project ELP.Model in which I defined few entities. I want to create database from it. It is approach called Code First. This is how looks one of my entity

To be able to enable migration and create database, we need to create Context. My Context Class looks like this

We need to install few packages before we start with actual migration.

To do it, open Package Manager Console (In VS Tools-> Nuget Package Manager -> Package Manager Console) set Default Project to your target project and install packages. Make sure to install the newest versions or the same versions for all.

To enable migrations in our project first we need to type in the same console Add-Migration MigrationName

and here is surprise. Not so easy man. I missed something. Yes exactly, we need to add implementation of IDbContextFactory<ELPContext>

1

This class should look like this:

Another Try to Add Migration and … another error…

2

What da… !? It looks like it is an issue in EF Core v 1.1.0. Work around for it is to change version to 1.0 :/ To do it we need to modify TargetFramework in csproj file from netcoreapp1.1 to netcoreapp1.0

3

4

Another try

Uff now everything works fine.

5

Take a look into Solution Explorer. Here we have new classes and Migrations folder.

6

The last step is to execute Update-Database command in Package Manager Console.

Fortunately this time it worked for me in first try. I didn’t expect it will be so easy 😉

To verify it, open SQL Server Object Explorer and check it. It should create new database.

7

Yeah, we have created database, nice. Now we can add something to it 🙂

[EN] How to mock DbSet in Entity Framework

duck-mock-dbset

duck as mock

In my project ELP I decided to start with core implementation of backend side. I started with service for sign in and register user accounts. I use TDD approach, so I create test with expected result that fails at the beginning and then I implement code to pass this test.

I created MembershipService in my project that is responsible for creating accounts, validating, etc. This service uses other services like UserService for getting users from database or UserRoleService for getting user roles. Services use context, (BTW I rejected using repository pattern, maybe I will describe more about it in the future) and context contains DbSets.

First problem that you can meet is how to mock this thing?

Let’s see how to write a test for method GetUserByUsername.

This is my test. I use xUnit testing framework and Moq for mocking. If you want to use it as I, you need to install it from Nuget Packages manager.

As you see I created list with one user and I want to pass it to my context, It will act like data get from database. First we need to create our DbSet for Users. I have little helper method for it. It is generic, so you can use it too.

Ok, so first test we have completed, but there’s one more thing that I wanted to share with you.

Let’s get back to my service that I mentioned before – MembershipService. I’d like to test CreateUser method which at the end adds user entity to User’s DbSet. Problem is with verifying it if you use mocks. If you check User’s DbSet from Context class there’s nothing in it. Null. And here comes Verify method from Moq framework that helps.

Here are 3 lines of code from my testing method, it executes CreateUserMethod, so I expect User’s DbSet will contain one item and UserRole’s DbSet will contain two items.

With help of Verify method result is as expected and test is green.

If you want to read more about testing Entity Framework you can go to https://msdn.microsoft.com/en-us/library/dn314429(v=vs.113).aspx

Do czego służy metoda AsNoTracking()?

Korzystając z Entity Frameworka warto zwracać uwagę na sposób pobierania danych.
W przypadku, gdy nie będziemy ich modyfikować, a chcemy jedynie pobrać dane tylko do odczytu, przydatna okaże się metoda AsNoTracking(). Wywołanie metody skutkuje brakiem śledzenia danych przez kontekst. Dzięki temu nie marnujemy niepotrzebnie zasobów.
Przyjrzyjmy się poniższemu przykładowi, w którym porównamy pobieranie danych z i bez metody AsNoTracking(). Na początek pobieramy dane standardowo. W tym celu modyfikujemy metodę Index() kontrolera LocationsController i debugując przechodzimy za linię kodu odpowiadającą za zwrócenie danych do widoku. W okienku watch podglądamy nasz obiekt kontekstu i widzimy, że 4 lokalizacje zostały do niego zapisane.

clip_image001

Teraz czas na wywołanie metody AsNoTracking() i upewnienie się, że dane nie są zapisywane w kontekście. Tym razem metoda Index() prezentuje się następująco:

Debugujemy, przechodzimy za ostatnią linię kodu w metodzie Index() i podglądamy nasz obiekt kontekstu.

clip_image002

Jak widać lokalizacje nie zostały tym razem zapisane do kontekstu, nie są przez niego śledzone. W tym przypadku oszczędności pamięci są niewielkie, ale wyobraźmy sobie gdybyśmy mieli takich lokalizacji tysiące, spowodowałoby to niepotrzebne straty. Dlatego należy zwrócić szczególną uwagę w takich sytuacjach i stosować AsNoTracking(), tam gdzie tylko jest to możliwe.