ASP.NET 6 REST API Tutorial | MongoDB Database


asp.net core rest api mongodb

Building a RESTful API service using Visual Studio 2022, ASP.NET 6 and MongoDB database.

Create new ASP.NET Core Web API project

I named the project StudentManagement. While creating the new ASP.NET Core Web API project, select the following options on Additional information page.

  • .NET 6.0 as the Target Framework
  • Configure for HTTPS - Check the checkbox
  • Use controllers - Check the checkbox
  • Enable OpenAPI support - Check the checkbox

asp.net 6 rest api tutorial

We discussed What is Swagger and OpenAPI specification in detail in Parts 29 and 30 of Azure tutorial. If you are new to these concepts please check out these 2 videos from the following course page.

Azure tutorial for beginners

Install MongoDB.Driver nuget package

visual studio mongodb driver

Map MongoDB to C# objects

Add Models folder and place the following Student.cs class file in it. When student data is retrieved from Mongo, the JSON data is mapped to this Student class in .NET and vice-versa.

[BsonIgnoreExtraElements]
public class Student
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; } = String.Empty;

    [BsonElement("name")]
    public string Name { get; set; } = String.Empty;

    [BsonElement("graduated")]
    public bool IsGraduated { get; set; }

    [BsonElement("courses")]
    public string[]? Courses { get; set; }

    [BsonElement("gender")]
    public string Gender { get; set; } = String.Empty;

    [BsonElement("age")]
    public int Age { get; set; }
}
  • [BsonId] attribute specifies that this is the Id field or property. In this example, the property Id maps to _id field in Mongo document.
  • [BsonRepresentation] attribute automatically converts Mongo data type to a .Net data type and vice-versa. In this example, Mongo data type ObjectId is automatically converted to string datatype and vice-versa.
  • Name property is decorated with the [BsonElement] attribute. So this means, Name property corresponds to name field in Mongo document. So, [BsonElement] attribute specifies the field in the Mongo document the decorated property corresponds to.
  • The property names (Name, Courses, Gender, Age) have the same name as the fields in the Mongo document (name, courses, gender, age). However the casing is different. In C# the properties start with an uppercase letter whereas in Mongo the field starts with lowercase. There are several approaches to handle this case sensitive mapping. One of the easiest and cleanest approaches is to use [BsonElement] attribute.
  • What to do if the JSON document in MongoDB contains more fields than the properties in the corresponding C# class? Well, we can use [BsonIgnoreExtraElements] attribute and instruct the serializer to ignore the extra elements.

All the following attributes are present in MongoDB.Bson.Serialization.Attributes

  • BsonId
  • BsonElement
  • BsonRepresentation
  • BsonIgnoreExtraElements

MongoDB connection string in ASP.NET Core

Store MongoDB connection information in appsettings.json file.

{
  "StudentStoreDatabaseSettings": {
    "StudentCoursesCollectionName": "studentcourses",
    "ConnectionString": "Your_MongoDB_ConnectionString",
    "DatabaseName": "myFirstDatabase"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Read MongoDB connection information

asp.net mongodb connection string

Add the following 2 files in the Models folder. This interface and the class provide strongly typed access to MongoDB connection information.

  1. IStudentStoreDatabaseSettings.cs
  2. StudentStoreDatabaseSettings.cs

IStudentStoreDatabaseSettings.cs

public interface IStudentStoreDatabaseSettings
{
    string StudentCoursesCollectionName { get; set; }
    string ConnectionString { get; set; }
    string DatabaseName { get; set; }
}

StudentStoreDatabaseSettings.cs

public class StudentStoreDatabaseSettings : IStudentStoreDatabaseSettings
{
    public string StudentCoursesCollectionName { get; set; } = String.Empty;
    public string ConnectionString { get; set; } = String.Empty;
    public string DatabaseName { get; set; } = String.Empty;
}

How to call MongoDB API from C#

mongodb c# web api

  1. For separation of concerns we will keep the code that calls Mongo API in a separate service layer.
  2. ASP.NET Web API Controller calls this service. 
  3. Add Services folder and place the 2 files in it (IStudentService.cs and StudentService.cs)

IStudentService.cs

public interface IStudentService
{
    List<Student> Get();
    Student Get(string id);
    Student Create(Student student);
    void Update(string id, Student student);
    void Remove(string id);
}

StudentService.cs

public class StudentService : IStudentService
{
    private readonly IMongoCollection<Student> _students;

    public StudentService(IStudentStoreDatabaseSettings settings, IMongoClient mongoClient)
    {
        var database = mongoClient.GetDatabase(settings.DatabaseName);
        _students = database.GetCollection<Student>(settings.StudentCoursesCollectionName);
    }

    public Student Create(Student student)
    {
        _students.InsertOne(student);
        return student;
    }

    public List<Student> Get()
    {
        return _students.Find(student => true).ToList();
    }

    public Student Get(string id)
    {
        return _students.Find(student => student.Id == id).FirstOrDefault();
    }

    public void Remove(string id)
    {
        _students.DeleteOne(student => student.Id == id);
    }

    public void Update(string id, Student student)
    {
        _students.ReplaceOne(student => student.Id == id, student);
    }
}

ASP.NET Core REST API Controller

Add the following StudentsController.cs file in the Controllers folder.

[Route("api/[controller]")]
[ApiController]
public class StudentsController : ControllerBase
{
    private readonly IStudentService studentService;

    public StudentsController(IStudentService studentService)
    {
        this.studentService = studentService;
    }
    // GET: api/<StudentsController>
    [HttpGet]
    public ActionResult<List<Student>> Get()
    {
        return studentService.Get();
    }

    // GET api/<StudentsController>/5
    [HttpGet("{id}")]
    public ActionResult<Student> Get(string id)
    {
        var student = studentService.Get(id);

        if (student == null)
        {
            return NotFound($"Student with Id = {id} not found");
        }

        return student;
    }

    // POST api/<StudentsController>
    [HttpPost]
    public ActionResult<Student> Post([FromBody] Student student)
    {
        studentService.Create(student);

        return CreatedAtAction(nameof(Get), new { id = student.Id }, student);
    }

    // PUT api/<StudentsController>/5
    [HttpPut("{id}")]
    public ActionResult Put(string id, [FromBody] Student student)
    {
        var existingStudent = studentService.Get(id);

        if (existingStudent == null)
        {
            return NotFound($"Student with Id = {id} not found");
        }

        studentService.Update(id, student);

        return NoContent();
    }

    // DELETE api/<StudentsController>/5
    [HttpDelete("{id}")]
    public ActionResult Delete(string id)
    {
        var student = studentService.Get(id);

        if (student == null)
        {
            return NotFound($"Student with Id = {id} not found");
        }

        studentService.Remove(student.Id);

        return Ok($"Student with Id = {id} deleted");
    }
}

We discussed building RESTful services from scratch in Part 5 of Web development with Blazor video series.

Configure Services 

In Program.cs file, configure the required services.

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<StudentStoreDatabaseSettings>(
                builder.Configuration.GetSection(nameof(StudentStoreDatabaseSettings)));

builder.Services.AddSingleton<IStudentStoreDatabaseSettings>(sp =>
    sp.GetRequiredService<IOptions<StudentStoreDatabaseSettings>>().Value);

builder.Services.AddSingleton<IMongoClient>(s =>
        new MongoClient(builder.Configuration.GetValue<string>("StudentStoreDatabaseSettings:ConnectionString")));

builder.Services.AddScoped<IStudentService, StudentService>();

Test REST API using Swagger

With Swagger it's easy to test the API calls directly in the browser. We discussed, what is swagger and how to use swagger in ASP.NET in parts 29 and 30 of Azure tutorial.

using swagger to test api





© 2020 Pragimtech. All Rights Reserved.