Lab01 - EmployeeManagement - Using ASP - NET Core Web API
Lab01 - EmployeeManagement - Using ASP - NET Core Web API
Introduction
Your manager has asked you to develop an application for simple
employee management. The relationship between project and employee is
One-to-Many, one employee is belong to one project, one project will have
zero or many employee. The application has to support adding, viewing,
modifying, and removing employee - a standardized usage action verbs
better known as Create, Read, Update, Delete (CRUD).
This lab explores creating an application using ASP.NET Core Web API to
create RESTful API, and ASP.NET Core Web Application with Model-View-
Controller. A SQL Server Database will be created to persist the product
data that will be used for reading and managing employee data by Entity
Framework Core.
1|Page
Lab Objectives
In this lab, you will:
Use the Visual Studio.NET to create ASP.NET Core Web Web API
Project.
Develop Web application using MVC Pattern.
Use Entity Framework to create a SQL Server database (Forward
Engineering Approach).
Develop Entity classes, DBContext class, DAO class to perform
CRUD actions using Entity Framework Core.
Apply Repository pattern to develop application.
Run the project and test the application actions.
2|Page
Guidelines
Create a Blank Solution
Step 01. Create a Solution named Lab01_ASP.NETCoreWebAPI..
3|Page
Activity 01: Identify entities
4|Page
Diagram
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1">
<Class Name="Entities.Exceptions.NotFoundException">
<Position X="4.5" Y="2.5" Width="1.75" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Exceptions\NotFoundException.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Entities.Exceptions.EmployeeNotFoundException">
<Position X="7" Y="3.5" Width="2.25" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Exceptions\EmployeeNotFoundException.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Entities.Exceptions.ProjectNotFoundException">
<Position X="7" Y="1.75" Width="2.25" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Exceptions\ProjectNotFoundException.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="System.Exception">
<Position X="2" Y="0.75" Width="2" />
<TypeIdentifier />
<Lollipop Position="0.2" />
</Class>
<Font Name="Segoe UI" Size="9" />
</ClassDiagram>
}
}
5|Page
Step 5 = Project Model
6|Page
Activity 02: Contracts Project - Interface
Step 01. Create Class Library Project named Contracts Objects
Add dependence: Add Project reference Entity
7|Page
{
void LogInfo(string message);
void LogWarn(string message);
void LogDebug(string message);
void LogError(string message);
}
}
}
8|Page
Activity 04: Class Library Repositories Project - create
an abstraction layer between the Data Access Layer
and the Business Logic Layer of the application
Step 01. Create Class Library Project named Repositories
Step 02. Add Project reference: Contracts, Entity
Step 03. Create config for entity
namespace Repository.Config
{
public class EmployeeConfig : IEntityTypeConfiguration<Employee>
{
public void Configure(EntityTypeBuilder<Employee> builder)
{
builder.HasData(
new Employee()
{
Id = new Guid("bc1ae16a-3572-40de-bd02-dab970697d20"),
ProjectId = new Guid("b67e3d43-23ef-444f-a022-5294810a5428"),
FirstName = "Ahmet",
LastName = "Yıldırım",
Age = 30,
Position = "Senior Developer"
}
);
}
}
}
namespace Repository.Config
{
public class ProjectConfig : IEntityTypeConfiguration<Project>
{
public void Configure(EntityTypeBuilder<Project> builder)
{
builder.HasData(
new Project
{
Id = new Guid("b67e3d43-23ef-444f-a022-5294810a5428"),
Name = "ASP.NET Core Web API Project",
Description = "Web Application Programming Interface",
Field = "Computer Science"
});
}
}
}
9|Page
protected RepositoryBase(RepositoryContext repositoryContext)
{
_repositoryContext = repositoryContext;
}
_projectRepository =
new Lazy<IProjectRepository>(() => new ProjectRepository(_context));
10 | P a g e
_employeeRepository =
new Lazy<IEmployeeRepository>(() => new EmployeeRepository(_context));
}
///
public class ProjectRepository : RepositoryBase<Project>, IProjectRepository
{
public ProjectRepository(RepositoryContext repositoryContext) : base(repositoryContext)
{
}
11 | P a g e
public IEnumerable<Project> GetAllProjects(bool trackChanges) =>
FindAll(trackChanges)
.OrderBy(p => p.Name)
.ToList();
namespace Shared.DataTransferObjects
{
public record EmployeeDtoForCreation(string FirstName, string LastName, int Age, string Position);
Project DOT
namespace Shared.DataTransferObjects
{
public record ProjectDto
{
public Guid Id { get; init; }
public string Name { get; init; }
public string Description { get; init; }
public string Field { get; init; }
};
namespace Shared.DataTransferObjects
{
public record ProjectDtoForCreation(string Name, string Description, string Field);
12 | P a g e
IEnumerable<EmployeeDto> GetAllEmployeesByProjectId(Guid projectId, bool trackChanges);
EmployeeDto GetOneEmployeeByProjectId(Guid projectId, Guid employeeId, bool trackChanges);
EmployeeDto CreateOneEmployeeByProjectId(Guid projectId, EmployeeDtoForCreation employeeDto, bool
trackChanges);
}
13 | P a g e
if(project is null)
throw new ProjectNotFoundException(projectId);
// Save (EF)
_repository.Employee.CreateEmployeeForProject(projectId,entity);
_repository.Save();
return _mapper.Map<EmployeeDto>(entity);
}
if (employee is null)
throw new EmployeeNotFoundException(employeeId);
return employeeDto;
}
14 | P a g e
_repository = repository;
_logger = logger;
_mapper = mapper;
}
_employeeService =
new Lazy<IEmployeeService>(() => new EmployeeService(repository, logger, mapper));
15 | P a g e
Activity 08: Create ProjectManagement.Presentation
library Project
Step 01. Install the following packages from NuGet:
[HttpGet]
public IActionResult GetAllEmployeeByProjectId(Guid projectId)
{
var employeeList = _service
.EmployeeService
.GetAllEmployeesByProjectId(projectId, false);
return Ok(employeeList);
}
return Ok(employee);
}
[HttpPost]
public IActionResult CreateOneEmployeeByProjectId(Guid projectId,
[FromBody] EmployeeDtoForCreation employeeDto)
{
EmployeeDto employee = _service
.EmployeeService
.CreateOneEmployeeByProjectId(projectId, employeeDto, true);
return CreatedAtRoute("GetOneEmployeeByProjectIdAndId",
new { projectId, id = employee.Id },
employee);
16 | P a g e
}
}
}
[HttpGet]
public IActionResult GetAllProjects()
{
var projects = _service.ProjectService.GetAllProjects(false);
return Ok(projects);
}
17 | P a g e
Step 02: rebuild project
Step 03. Add Connection string (also add JSON appsettings.json file)
{"ConnectionStrings": {
"sqlConnection": "server =(local); database =
MSSQLLocalDB;uid=sa;pwd=123456;Trusted_Connection=True;Encrypt=False"
},
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
migrationBuilder.CreateTable(
name: "Employees",
columns: table => new
{
EmployeeId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
FirstName = table.Column<string>(type: "nvarchar(max)", nullable: false),
LastName = table.Column<string>(type: "nvarchar(max)", nullable: false),
Age = table.Column<int>(type: "int", nullable: true),
Position = table.Column<string>(type: "nvarchar(max)", nullable: true),
ProjectId = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Employees", x => x.EmployeeId);
table.ForeignKey(
name: "FK_Employees_Projects_ProjectId",
column: x => x.ProjectId,
principalTable: "Projects",
principalColumn: "ProjecId",
18 | P a g e
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Projects",
columns: new[] { "ProjecId", "Description", "Field", "ImageUrl", "Name" },
values: new object[] { new Guid("b67e3d43-23ef-444f-a022-5294810a5428"), "Web Application Programming
Interface", "Computer Science", null, "ASP.NET Core Web API Project" });
migrationBuilder.InsertData(
table: "Employees",
columns: new[] { "EmployeeId", "Age", "FirstName", "LastName", "Position", "ProjectId" },
values: new object[] { new Guid("bc1ae16a-3572-40de-bd02-dab970697d20"), 30, "Ahmet", "Yıldırım", "Senior
Developer", new Guid("b67e3d43-23ef-444f-a022-5294810a5428") });
migrationBuilder.CreateIndex(
name: "IX_Employees_ProjectId",
table: "Employees",
column: "ProjectId");
}
migrationBuilder.DropTable(
name: "Projects");
}
}
}
}
Class RepositoryContextModelSnapshot
namespace ProjectManagement.Migrations
{
[DbContext(typeof(RepositoryContext))]
partial class RepositoryContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.0")
19 | P a g e
.HasAnnotation("Relational:MaxIdentifierLength", 128);
modelBuilder.Entity("Entities.Models.Employee", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier")
.HasColumnName("EmployeeId");
b.Property<int?>("Age")
.HasColumnType("int");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Position")
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("ProjectId")
.IsRequired()
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("ProjectId");
b.ToTable("Employees");
b.HasData(
new
{
Id = new Guid("bc1ae16a-3572-40de-bd02-dab970697d20"),
Age = 30,
FirstName = "Ahmet",
LastName = "Yıldırım",
Position = "Senior Developer",
ProjectId = new Guid("b67e3d43-23ef-444f-a022-5294810a5428")
});
});
modelBuilder.Entity("Entities.Models.Project", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier")
.HasColumnName("ProjecId");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("Field")
.HasColumnType("nvarchar(max)");
20 | P a g e
b.Property<string>("ImageUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(60)
.HasColumnType("nvarchar(60)");
b.HasKey("Id");
b.ToTable("Projects");
b.HasData(
new
{
Id = new Guid("b67e3d43-23ef-444f-a022-5294810a5428"),
Description = "Web Application Programming Interface",
Field = "Computer Science",
Name = "ASP.NET Core Web API Project"
});
});
modelBuilder.Entity("Entities.Models.Employee", b =>
{
b.HasOne("Entities.Models.Project", "Project")
.WithMany("Employees")
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Project");
});
modelBuilder.Entity("Entities.Models.Project", b =>
{
b.Navigation("Employees");
});
#pragma warning restore 612, 618
}
}
21 | P a g e
{
public static void ConfigureExceptionHandler(this WebApplication app,
ILoggerManager logger)
{
app.UseExceptionHandler(appError =>
{
appError.Run(async context =>
{
context.Response.ContentType = "application/json";
22 | P a g e
);
}
CreateMap<Employee, EmployeeDto>().ReverseMap();
CreateMap<EmployeeDtoForCreation, Employee>();
}
}
23 | P a g e
Step 07. Update Class Program.CS
var builder = WebApplication.CreateBuilder(args);
LogManager.LoadConfiguration(String.Concat(Directory.GetCurrentDirectory(), "/nlog.config"));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.ConfigureCors();
builder.Services.ConfigureLoggerManager();
builder.Services.ConfigureSqlContext(builder.Configuration);
builder.Services.ConfigureRepositoryManager();
builder.Services.ConfigureServiceManager();
builder.Services.AddAutoMapper(typeof(Program));
builder.Services.AddControllers(config =>
{
config.RespectBrowserAcceptHeader = true;
config.ReturnHttpNotAcceptable = true; // 406
})
.AddXmlDataContractSerializerFormatters()
.AddCustomCSVFormatter()
24 | P a g e
.AddApplicationPart(typeof(ProjectManagement.Presentation
.AssemblyReference).Assembly);
if (app.Environment.IsProduction())
app.UseHsts();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.UseCors("CorsPolicy");
app.Run();
25 | P a g e
26 | P a g e
Activity 05: Create ProductManagementAPI Project
(Work with ASP.NET Core Web API template)
Step 01. Create ASP.NET Core Web API Project named
ProductManagementAPI
Step 02. Add Project reference: Repository Project
Step 03. Add ApiController named ProductsControllers.cs
27 | P a g e
Step 04. Test API project with OpenAPI or Postman
28 | P a g e
Activity 06: ASP.NET Core Web Application with
Model-View-Controller Project
Step 01. Create ASP.NET Core Web App (Model-View-Controller) named
ProductManagementWebClient
Step 02. Add Project reference: BusinessObjects Project (or create new
DTO classes)
Step 03. Create Controller to connect to ProductManagementAPI
29 | P a g e
The detail of functions in ProductController (Web App MVC).
30 | P a g e
Step 04. Create View
31 | P a g e
Step 05. Test the function of Web Client
32 | P a g e
Activity 07: Build and run Project. Test all CRUD
actions
Note: Choose the option for multiple startup projects.
33 | P a g e