Programming tutorials shows us a land of promise where everything happens as you think; as soon as you think. But real world doesn’t work that way most of the times. Here; you spend hours debugging some CORS error or thinking why your database table Id column is not auto-incrementing. For the last 2 days; I am participating in a coding interview which spans 2 days and these series of blog is based on that experience – what am I thinking at each stage; what is the issue and how I am resolving them. This is the second part of that.
Adding DB Context
namespace dev_test
{
public class DatabaseContext : DbContext
{
public DatabaseContext()
: base()
{
}
public DbSet<User> Users { get; set; }
public DbSet<Survey> Surveys { get; set; }
public DbSet<Question> Questions { get; set; }
public DbSet<Answer> Answers { get; set; }
}
}
At this point; while adding stuff to DatabaseContext file; error was shown and needed to add nuget package Microsoft.EntityFrameworkCore and relevant packages.
Added the following line to appsettings.json file –
"ConnectionStrings": {
"DBConnection": "server=(localdb)\\MSSQLLocalDB;database=dev_test;Trusted_Connection=true"
}
As there is no startup.cs file in the project; adding following line was not possible.
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
At this point; modified the Program.cs class to look like this-
using dev_test;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
And got the following error: DbContextOptionsBuilder does not contain a definition for ‘usesqlserver’ and no extension method ‘usesqlserver’. Installed nuget packages and added “using Arch.EntityFrameworkCore;” before the file. Now getting “options is not null here” error. Turns out; “using Arch.EntityFrameworkCore;” was not the right solution; it should be – "using Microsoft.EntityFrameworkCore;"
The difference between the packages “Arch.EntityFrameworkCore” and “Microsoft.EntityFrameworkCore” is that Arch.EntityFrameworkCore is a third-party package that provides additional functionality on top of the standard Microsoft.EntityFrameworkCore package. It may contain additional classes, methods, and features that are not included in the Microsoft.EntityFrameworkCore package. On the other hand, Microsoft.EntityFrameworkCore is an official package from Microsoft that provides the core functionality for working with Entity and databases in .NET applications. It is the foundation for all Entity Framework Core functionality, and it is typically included as a dependency in other packages that provide additional functionality.
After that the program.cs file looks like this –
using Microsoft.EntityFrameworkCore;
using dev_test;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DBConnection");
builder.Services.AddDbContext<DatabaseContext>(x => x.UseSqlServer(connectionString));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
...
Tried to run the project but got the following error –fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Ambiguous HTTP method for action - dev_test.Controllers.UserController.Get (dev_test). Actions require an explicit HttpMethod binding for Swagger/OpenAPI 3.0
Added [HttpGet]
and [HttpPost]
before the UserController
actions; and it worked out perfectly fine.
Also; removed the default WeatherController and associated files.
When running this project in Swagger; it gives the following error – System.InvalidOperationException: Unable to resolve service for type 'dev_test.Services.Contracts.IUserService' while attempting to activate 'dev_test.Controllers.UserController'.
Which means we forgot to register the dependencies. After adding them to our program.cs; it works perfectly fine.
Another problem arises though; the database isn’t connecting as I am trying to connect over local server. Changing "DBConnection": "server=(localdb)\MSSQLLocalDB;database=dev_test;Trusted_Connection=true"
to "DBConnection":"Server=localhost;Database=dev_test;Trusted_Connection=True;MultipleActiveResultSets=true,TrustServerCertificate=True"
has solved the connection issue; but it is throwing “Invalid value for key ‘Multiple Active Result Sets’ error.”
Changing yet again to "DBConnection": "Server=localhost;Database=dev_test;Trusted_Connection=True;TrustServerCertificate=True"
solved the issue; but showing “Invalid object name ‘Users’.” error.
Turns out; in dbcontext; name should be singular instead of plural like this:
using dev_test.DTOs; // WRONG CODE
using Microsoft.EntityFrameworkCore;
namespace dev_test
{
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options){}
public DbSet<User> Users { get; set; }
public DbSet<Survey> Surveys { get; set; }
public DbSet<Question> Questions { get; set; }
public DbSet<Answer> Answers { get; set; }
}
}
using dev_test.DTOs; // RIGHT CODE
using Microsoft.EntityFrameworkCore;
namespace dev_test
{
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options){}
public DbSet<User> User { get; set; }
public DbSet<Survey> Survey { get; set; }
public DbSet<Question> Question { get; set; }
public DbSet<Answer> Answer { get; set; }
}
}
And for getting the user list; the controller signature should be – public ActionResult> Get()
Our user insert is working for the time being; though it is requiring us to manually put an different id each time. We need to address this issue later.
But first; we need to create our front-end application.
Let’s get into it and use angular-cli command to create an angular project with routing.
Setting Up Angular Project
We set up the angular project the common way; start with angular-cli project; remove app.component.html file; add some component of our own and set up a service file to call to the backend. The initial setup might look like this –
And the ever innocuous user-list.component.ts might look like this –
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpClientService } from 'src/app/http-client.service';
@Component({
selector: 'app-use-list',
templateUrl: './use-list.component.html',
styleUrls: ['./use-list.component.scss']
})
export class UseListComponent implements OnInit {
userList = [];
constructor(client: HttpClientService) {
client.getData("user").subscribe((res) => console.log(res));
}
ngOnInit(): void {
}
}
But here comes the issues. While running this project; we conveniently greeted with an error like this –
Other episodes in this series:
First Part
Second Part
Third Part
Fourth Part
And the code is given is updated into –
Github
2 thoughts on “Coding Adventures: The Truth About Programming Outside Tutorials, Part 2”