Web API – ASP.NET Core

In this post, we will see how to create a RESTful Web Service with ASP.NET Core.

We open Visual Studio 2019 and select the template ASP.NET Core Web Application.


Then, we select the API template, framework 2.2 and then we click on Create.


At the end, we will have a project like that:



If we run the project, this will be the output:




Now, we create a folder called Model where we will add Entities and the Datacontext:

[User.cs]

public class User
{
    [Key]
    public Int64 Id { get; set; }
    public String Username { get; set; }
    public Int32 TypeUserId { get; set; }
    public DateTime CreateDate { get; set; }

    public UserType UserType { get; set; }
}


[UserType.cs]

public class UserType
{
   public Int32 Id { get; set; }
   public String Name { get; set; }

   public virtual ICollection<User> Users { get; set; }
}


[ProjectContext.cs]

public class ProjectContext:DbContext
{
   public ProjectContext(DbContextOptions<ProjectContext> options):base(options)
   {
   }

   public DbSet<User> Users { get; set; }
   public DbSet<UserType> UserTypes { get; set; }
}



Now, in order to register the DB context in the application, we will modify the method ConfigureServices in Startup.cs.
We use this method to add services or DBContext to the container, because it gets called by the runtime.
In this example, we will use a feature of Entity Framework Core, called UseInMemoryDatabase, that is the addition of an in-memory data provider.
With this feature we can prototype or testing applications without having to set up a database.

public class Startup
{
   public Startup(IConfiguration configuration)
   {
       Configuration = configuration;
   }

   public IConfiguration Configuration { get; }

   // This method gets called by the runtime. Use this method to add services to the container.
   public void ConfigureServices(IServiceCollection services)
   {
       services.AddDbContext<ProjectContext>(opt => opt.UseInMemoryDatabase("ProjectDB"));
       services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
   }
   ..
   ..
   ..
}


Now, in order to insert data in the DbContext, we create a class called SeedData:

public static class SeedData
{
    public static void CreateData(ProjectContext dbContext)
    {
        UserType objUserType1 = new UserType { Id = 1, Name = "Admin" };
        UserType objUserType2 = new UserType { Id = 2, Name = "Reader" };
        UserType objUserType3 = new UserType { Id = 3, Name = "Writer" };

        dbContext.UserTypes.Add(objUserType1);
        dbContext.UserTypes.Add(objUserType2);
        dbContext.UserTypes.Add(objUserType3);


        User objUser1 = new User { Id = 1000, Username = "Ad1000", TypeUser = 1, CreateDate = DateTime.Now.AddDays(-100) };
        User objUser2 = new User { Id = 1001, Username = "Ad2000", TypeUser = 1, CreateDate = DateTime.Now.AddDays(-30) };

        User objUser3 = new User { Id = 2010, Username = "Re7600", TypeUser = 2, CreateDate = DateTime.Now.AddDays(-100) };
        User objUser4 = new User { Id = 2020, Username = "Re7040", TypeUser = 2, CreateDate = DateTime.Now.AddDays(-45) };
        User objUser5 = new User { Id = 2021, Username = "Re0001", TypeUser = 2, CreateDate = DateTime.Now.AddDays(-37) };

        User objUser6 = new User { Id = 3080, Username = "Wr0300", TypeUser = 3, CreateDate = DateTime.Now.AddDays(-63) };
        User objUser7 = new User { Id = 30802, Username = "Wr1010", TypeUser = 3, CreateDate = DateTime.Now.AddDays(-53) };

        dbContext.Users.Add(objUser1);
        dbContext.Users.Add(objUser2);
        dbContext.Users.Add(objUser3);
        dbContext.Users.Add(objUser4);
        dbContext.Users.Add(objUser5);
        dbContext.Users.Add(objUser6);
        dbContext.Users.Add(objUser7);

        dbContext.SaveChanges();
    }
}


Now a question: Where can we call the method CreateData?
The answer is “in the Program file”.
For doing that, we will create a class called ExtensionClass where, we will insert the Extension Method for the interface IWebHost.

public static class ExtensionClass
{
    public static IWebHost CreateDatabaseInMemory(this IWebHost webHost)
    {
        var serviceScopeFactory = (IServiceScopeFactory)webHost.Services.GetService(typeof(IServiceScopeFactory));

        using (var scope = serviceScopeFactory.CreateScope())
        {
            var services = scope.ServiceProvider;
            var dbContext = services.GetRequiredService<ProjectContext>();

            SeedData.CreateData(dbContext);
        }

        return webHost;
    }
}


Now, we can call CreateDatabaseInMemory in the Program file:

public class Program
{
    public static void Main(string[] args)
    {
          CreateWebHostBuilder(args).Build().CreateDatabaseInMemory().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}


For a best practice and to avoid a possible circular dependency, we will create a UserViewModel to use as output for our Web API.

public class UserVM
{
    public Int64 Id { get; set; }
    public String Username { get; set; }
    public String TypeUserName { get; set; }
    public DateTime CreateDate { get; set; }
}


Finally, we create a controller called UserController in order to get the Users list:

[UserController.cs]

[Route("api/[controller]")]
public class UserController : Controller
{
    private readonly ProjectContext _contextProject;

    // With the dependency injection we put the DbContext into controller
    public UserController(ProjectContext contextProject)
    {
       _contextProject = contextProject;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<UserVM>>> GetListUsers()
    {
        // With the command Include, the system will load all information about usertype
        return await _contextProject.Users.Include(ll => ll.UserType).Select(ll =>
              new UserVM()
              {
                  Id = ll.Id,
                  Username = ll.Username,
                  CreateDate = ll.CreateDate.ToShortDateString(),
                  TypeUserName = ll.UserType.Name
              }).ToListAsync();
    }
}



Now, we run the application and with Postman we can verify the result: