Home .NET ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1

ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1

by admin

ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1

Introduction

A short course on creating a simple web application using ASP.NET Core technologies, Entity Framework, Microsoft SQL Server and Angular framework. We’ll test the Web API using the application Postman
The course consists of several parts :

  1. Creating Web APIs using ASP.NET Web API and Entity Framework Core.
  2. Implementing a user interface in Angular.
  3. Adding authentication to the application.
  4. Extending the application model and looking at additional Entity Framework features.

Part 1. Creating Web APIs using ASP.NET Web API and Entity Framework Core


As an example, we will look at what has already become a classic to-do list application. I will use Visual Studio 2019 to develop the application (the process is similar in Visual Studio 2017).

Project creation

Create a new ASP.NET Core Web Application project in Visual Studio:
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
Let’s name the application and specify the path to the directory with the project :
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
And let’s choose the API application template:
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1

Model

Let’s create the Models directory and add the first TodoItem.cs class to the new directory, whose objects will describe some tasks of the to-do list in the application :

public class TodoItem{public int Id { get; set; }public string TaskDescription { get; set; }public bool IsComplete { get; set; }}

As a DBMS we will use Sql Server, and we will access the database through Entity Framework Core and first install the framework through the built-in NuGet package manager:
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
One of the approaches in working with Entity Framework is the "Code-First" approach. The essence of the approach is that based on the application model (in our case, the model is a single class – TodoItem.cs) the database structure (tables, primary keys, links) is formed, all this work is done behind the scenes and we do not work directly with SQL. The mandatory condition for the model class is the presence of the primary key field. By default Entity Framework searches an integer field whose name contains a substring "id" and forms a primary key on its basis. You can override this behavior using special attributes or using Fluent API capabilities.
The main component in working with Entity Framework is the database context class, through which you actually access the data in the tables :

public class EFTodoDBContext :DbContext{public EFTodoDBContext(DbContextOptions<EFTodoDBContext> options) : base(options){ }public DbSet<TodoItem> TodoItems{ get; set; }}

The DbContext base class creates a database context and provides access to Entity Framework functionality.
To store the application data we will use SQL Server 2017 Express The connection strings are stored in a JSON file called appsettings.json:

{"ConnectionStrings": {"DefaultConnection": "Server=.\SQLEXPRESS;Database=Todo;Trusted_Connection=true"}}

Next you need to modify the Startup.cs class by adding the following code to the ConfigureServices() method :

services.AddDbContext<EFTodoDBContext> (options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));

The AddDbContext() method configures the services provided by the Entity Framework Core infrastructure for the EFTodoDBContext base context class. The argument of the AddDbContext () method is a lambda expression that receives the options object that configures the database for the context class. In this case, the database is configured using the UseSqlServer() method and specifying a connection string.
Let’s define the basic operations for working with tasks in the ITodoRepository interface:

public interface ITodoRepository{IEnumerable<TodoItem> Get();TodoItem Get(int id);void Create(TodoItem item);void Update(TodoItem item);TodoItem Delete(int id);}

This interface allows us not to think about the specific implementation of the data warehouse, maybe we have not decided on the exact DBMS or ORM framework, it does not matter now, the class describing the data access will inherit from this interface.
Let’s implement the repository which will inherit from ITodoRepository and use EFTodoDBContext as a data source:

public class EFTodoRepository : ITodoRepository{private EFTodoDBContext Context;public IEnumerable<TodoItem> Get(){return Context.TodoItems;}public TodoItem Get(int Id){return Context.TodoItems.Find(Id);}public EFTodoRepository(EFTodoDBContext context){Context = context;}public void Create(TodoItem item){Context.TodoItems.Add(item);Context.SaveChanges();}public void Update(TodoItem updatedTodoItem){TodoItem currentItem = Get(updatedTodoItem.Id);currentItem.IsComplete = updatedTodoItem.IsComplete;currentItem.TaskDescription = updatedTodoItem.TaskDescription;Context.TodoItems.Update(currentItem);Context.SaveChanges();}public TodoItem Delete(int Id){TodoItem todoItem = Get(Id);if (todoItem != null){Context.TodoItems.Remove(todoItem);Context.SaveChanges();}return todoItem;}}

Controller

The controller, the implementation of which will be described below, will know nothing about the EFTodoDBContext data context, but will only use the ITodoRepository interface in its work, which allows you to change the data source without changing the controller at the same time. This approach by Adam Freeman in his book "Entity Framework Core 2 for ASP.NET Core MVC for Professionals." Named – "Warehouse pattern".
The controller implements handlers for standard HTTP request methods : GET, POST, PUT, DELETE, which will change the state of our tasks described in class TodoItem.cs.
Let’s add the TodoController.cs class to the Controllers directory with the following contents :

[Route("api/[controller]")]public class TodoController : Controller{ITodoRepository TodoRepository;public TodoController(ITodoRepository todoRepository){TodoRepository = todoRepository;}[HttpGet(Name = "GetAllItems")]public IEnumerable<TodoItem> Get(){return TodoRepository.Get();}[HttpGet("{id}", Name = "GetTodoItem")]public IActionResult Get(int Id){TodoItem todoItem = TodoRepository.Get(Id);if (todoItem == null){return NotFound();}return new ObjectResult(todoItem);}[HttpPost]public IActionResult Create([FromBody] TodoItem todoItem){if (todoItem == null){return BadRequest();}TodoRepository.Create(todoItem);return CreatedAtRoute("GetTodoItem", new { id = todoItem.Id }, todoItem);}[HttpPut("{id}")]public IActionResult Update(int Id, [FromBody] TodoItem updatedTodoItem){if (updatedTodoItem == null || updatedTodoItem.Id != Id){return BadRequest();}var todoItem = TodoRepository.Get(Id);if (todoItem == null){return NotFound();}TodoRepository.Update(updatedTodoItem);return RedirectToRoute("GetAllItems");}[HttpDelete("{id}")]public IActionResult Delete(int Id){var deletedTodoItem = TodoRepository.Delete(Id);if (deletedTodoItem == null){return BadRequest();}return new ObjectResult(deletedTodoItem);}}

An attribute describing the route pattern for accessing the controller is specified before the class definition : [Route("api/[controller]")]. TodoController will be accessed via the following route : https://<ip host> :<port> /api/todo. The [controller] specifies the name of the controller class in lowercase, omitting the "Controller" part.
A special attribute of the form : [<method HTTP> ("parameter", Name = "method alias")] is specified before each method definition in the TodoController. This attribute specifies which HTTP request will be handled by this method, the parameter that is passed to the request URI and the method alias that can be used to resend the request. If no attribute is specified, by default the MVC framework will try to find the most appropriate method in the controller to process the request based on the method name and specified parameters in the request, so if no attribute is specified in TodoController for Get() method, then when HTTP request is made by GET: https://<ip host> :<port> /api/todo, the framework will define Get() controller method to process request.
In its constructor, the controller gets a reference to an object of type ITodoRepository, but so far the MVC framework doesn’t know which object to substitute when creating the controller. We need to create a service that explicitly resolves this dependency, to do that let’s make some changes to the Startup.cs class, adding the following code to the ConfigureServices() method:

services.AddTransient<ITodoRepository, EFTodoRepository> ();

The AddTransient<ITodoRepository, EFTodoRepository> () method defines a service that creates a new instance of the EFTodoRepository class every time an instance of type ITodoRepository is required, such as in a controller.
Full code of Startup.cs class:

public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }public void ConfigureServices(IServiceCollection services){services.AddControllers();services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);services.AddDbContext<EFTodoDBContext> (options => options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"]));services.AddTransient<ITodoRepository, EFTodoRepository> ();}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseHttpsRedirection();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllers();});}}

Migrations

In order for Entity Framework to generate a database and tables based on the model, you need to use the database migration process. Migrations are a group of commands that perform database preparation to work with Entity Framework. They are used to create and synchronize the database. The commands can be executed either in the Package Manager Console or in the Developer Power Shell. We will use the Package Manager Console, to work with Entity Framework you will need to install the Microsoft.EntityFrameworkCore.Tools:
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
Run the Package Manager console and run the command Add-Migration Initial :
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
A new directory appears in the project – Migrations, which will store migration classes, on the basis of which the objects will be created in the database after the execution of the Update-Database command:
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
Web API is ready, running the application on the local IIS Express we can test the operation of the controller.

WebAPI testing

Let’s create a new collection of queries in Postman called TodoWebAPI:
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
Since our database is empty, let’s test the creation of a new task. In controller the Create() method is responsible for creating tasks, it will process HTTP request sent by POST method and will contain serialized TodoItem in JSON format in request body. The [FromBody] attribute before todoItem parameter in Create() method tells MVC framework to deserialize TodoItem object from request body and pass it as a parameter to method. Let’s create a request in Postman that sends a request to the webAPI to create a new task :
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
After successful creation of a task, the Create() method redirects the request to the Get() method with the alias "GetTodoItem" and sends Id of the newly created task as a parameter, as a result, we will get the created task object in JSON format in response to the request.
Sending HTTP request by PUT method and specifying in URI Id(https://localhost:44370/api/todo/1) of already created object, and in the body of request sending object with some changes in JSON format, we will change this object in the base :
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
HTTP request with GET method without parameters will get all objects in the base :
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
HTTP request with DELETE method and specifying Id of object in URI(https://localhost:44370/api/todo/2), will delete object from database and return JSON with deleted task :
ASP.NET Web API + Entity Framework + Microsoft SQL Server + Angular.Часть 1
That’s all, in the next part we will implement the user interface using the Angular JavaScript framework.

You may also like