Access AWS DynamoDb in .Net Application using C#

DynamoDb is a popular No SQL Database Services offered by AWS. It's mainly used in Serverless architecture where DynamoDb is mainly used as a persistence object.

Accessing Data in DynamoDb in a Middle Tier like REST API Backend Services is a common requirement of the Web Application. In this article, I will be giving code examples to access DynamoDb in ASP.Net Core Web API using C# programming language.

To Access DynamoDb from ASP.NET Core Web API, you need AWS access key id and AWS Secret Access Key which you can find in the My Security Credentials page in AWS Browser Console by clicking on your name dropdown in the upper right corner.

Let's assume we have a Student table in Dynamodb which has schema has below and we want the normal CRUD( Create, Read, Update and Delete) operation with the Student Data.

student_table_aws_dynamodb.png

Let's Create an Interface in C# like below to implement the CRUD operation.

IStudentService

using AWSServerlessBlogApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AWSServerlessBlogApi.Services
{
    public interface IStudentService
    {
        Task<IEnumerable<Student>> GetAllStudents();
        Task<StudentGetStudent(int studentId);
        Task AddStudent(Student student);
        Task UpdateStudent(Student studentint studentId);
        Task DeleteStudent(int studentId);
    }
}



Let's implement this interface in a class named "StudentService" so to access DynamoDb from your application we need to install a package named AWSSDK.DynamoDBv2 from Nuget Package Manager. ​I am using version 3.3.105.34 ​but you can higher version if my code example is not giving any error.

First, we need to inject DynamoDb Context using Constructor Injection like below

IDynamoDBContext DDBContext { getset; }

public StudentService()
  {
     var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 };
     this.DDBContext = new DynamoDBContext(
new AmazonDynamoDBClient("aws-access-key-id""aws-secret-access-key"RegionEndpoint.APSouth1), config);
  }


Let's implement the GetAllStudent() method of the interface like below

public async Task<IEnumerable<Student>> GetAllStudents()
  {
      var search = DDBContext.ScanAsync<Student>(null);
      var allStudents = await search.GetNextSetAsync();
      return allStudents;
  }


In the above example, you can see that we are using DynamoDb Context to get the entire data Student Table.

Also, Please  note we have to create a Student Model ​in your application exactly the same as the Schema of the Student table of DynamoDb like below

Student.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AWSServerlessBlogApi.Models
{
    public class Student
    {
        public int Id { getset; }
        public string StudentName { getset; }
        public int RollNumber { getset; }
        public string StudentClass { getset; }
        public bool IsActive { getset; }
    }
}


If you are having the model property name different compared to the Database column name then first you need to retrieve the data and then do the mapping to the object of your backend Student class.

GetStudent(int studentId)

public async Task<StudentGetStudent(int studentId)
 {
    List<ScanConditionconditions = new List<ScanCondition>();
    conditions.Add(new ScanCondition("Id"ScanOperator.EqualstudentId));
    var search = DDBContext.ScanAsync<Student>(conditions);
    var student = await search.GetNextSetAsync().ConfigureAwait(false);
   return student.SingleOrDefault(x => x.Id == studentId);
 }


In the above example, we can see we have ScanCondition through which we can apply multiple conditions and get the final result.

StudentService.cs

using Amazon;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using AWSServerlessBlogApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AWSServerlessBlogApi.Services
{
    public class StudentService : IStudentService
    {
        IDynamoDBContext DDBContext { getset; }

        public StudentService()
        {
            var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 };
            this.DDBContext = new DynamoDBContext(new AmazonDynamoDBClient("aws-access-key-id""aws-secret-access-key"RegionEndpoint.APSouth1), config);
        }

        public async Task AddStudent(Student student)
        {
            await DDBContext.SaveAsync<Student>(student).ConfigureAwait(false);
        }

        /// <summary>
        /// Soft Delete of the existing Student
        /// </summary>
        /// <param name="studentName"></param>
        /// <returns></returns>
        public async Task DeleteStudent(int studentId)
        {
            var existingStudent = await GetStudent(studentId).ConfigureAwait(false);
            existingStudent.IsActive = false;
            await UpdateStudent(existingStudentstudentId);
        }

        public async Task<IEnumerable<Student>> GetAllStudents()
        {
            var search = DDBContext.ScanAsync<Student>(null);
            var allStudents = await search.GetNextSetAsync();
            return allStudents;
        }

        public async Task<StudentGetStudent(int studentId)
        {
            List<ScanConditionconditions = new List<ScanCondition>();
            conditions.Add(new ScanCondition("Id"ScanOperator.EqualstudentId));
            var search = DDBContext.ScanAsync<Student>(conditions);
            var student = await search.GetNextSetAsync().ConfigureAwait(false);
            return student.SingleOrDefault(x => x.Id == studentId);
        }

        public async Task UpdateStudent(Student studentint studentId)
        {
            var existingStudent = await DDBContext.LoadAsync<Student>(studentId);
            existingStudent.StudentName = student.StudentName;
            existingStudent.StudentClass = student.StudentClass;
            existingStudent.RollNumber = student.RollNumber;
            existingStudent.IsActive = student.IsActive;
            await DDBContext.SaveAsync<Student>(existingStudent);
        }
    }
}


Now we can inject the above Student Service in our controller class as below to perform the CRUD operation.

StudentController.cs

using AWSServerlessBlogApi.Models;
using AWSServerlessBlogApi.Services;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace StudentAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StudentController : ControllerBase
    {
        private readonly IStudentService _studentService;
        public StudentController(IStudentService studentService)
        {
            _studentService = studentService ?? throw new ArgumentNullException(nameof(studentService));
        }

        [HttpGet("")]
        public async Task<IActionResultGetAllStudent()
        {

            var res = await _studentService.GetAllStudents().ConfigureAwait(false);
            return Ok(res);
        }

        [HttpGet("{studentId}")]
        public async Task<IActionResultGetStudent(int studentId)
        {
            var res = await _studentService.GetStudent(studentId).ConfigureAwait(false);
            return Ok(res);
        }

        [HttpPost("")]
        public async Task<IActionResultAddStudent([FromBodyStudent student)
        {
            await _studentService.AddStudent(student).ConfigureAwait(false);
            return Ok("Student Addition Successful");
        }

        [HttpPut("{studentId}")]
        public async Task<IActionResultUpdateStudent([FromBodyStudent studentint studentId)
        {
            await _studentService.UpdateStudent(studentstudentId).ConfigureAwait(false);
            return Ok("Student Update Successful");
        }

        [HttpDelete("{studentId}")]
        public async Task<IActionResultDeleteStudent(int studentId)
        {
            // Use student object to delete the student in DB
            await _studentService.DeleteStudent(studentId).ConfigureAwait(false);
            return Ok("Deleted the Student");
        }
    }
}


Hope this article will help you to normal CRUD operation for DynamoDb tables in ASP.Net Core.





Share This Post

Linkedin
Fb Share
Twitter Share
Reddit Share

Support Me

Buy Me A Coffee