Create WebAPI

Create a WebAPI Project to consume data from Cosmos DB

Create project

Let us create an asp.net web api project inside a folder called CosmosDemo by running the following command:

dotnet new webapi

Create Item model in a folder called Models

At the root of your project, create the Models folder and a class called Item inside it. Replace the contents of it with the code shown below:

using Newtonsoft.Json;

namespace CosmosDemo.Models;

public class Item
{
    [JsonProperty(PropertyName = "id")] 
    public string? Id { get; set; }

    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }

    [JsonProperty(PropertyName = "description")]
    public string Description { get; set; }

    [JsonProperty(PropertyName = "isComplete")]
    public bool Completed { get; set; }
}

Create a folder called Services

Inside the folder define an interface ICosmosDbService as given in the code below:

using CosmosDemo.Models;

namespace CosmosDemo.Services;

public interface ICosmosDbService
{
    Task<IEnumerable<Item>> GetMultipleAsync(string query);
    Task<Item> GetAsync(string id);
    Task AddAsync(Item item);
    Task UpdateAsync(string id, Item item);
    Task DeleteAsync(string id);
}

In the same folder create a class CosmosDbService that implements the interface as shown below:

using CosmosDemo.Models;
using Microsoft.Azure.Cosmos;

namespace CosmosDemo.Services;

public class CosmosDbService : ICosmosDbService
{
    private Container _container;

    public CosmosDbService(CosmosClient cosmosDbClient,string databaseName,string containerName)
    {
        _container = cosmosDbClient.GetContainer(databaseName, containerName);
    }

    public async Task AddAsync(Item item)
    {
        await _container.CreateItemAsync(item, new PartitionKey(item.Id));
    }

    public async Task DeleteAsync(string id)
    {
        await _container.DeleteItemAsync<Item>(id, new PartitionKey(id));
    }

    public async Task<Item> GetAsync(string id)
    {
        try
        {
            var response = await _container.ReadItemAsync<Item>(id, new PartitionKey(id));
            return response.Resource;
        }
        catch (CosmosException) //For handling item not found and other exceptions
        {
            return null;
        }
    }

    public async Task<IEnumerable<Item>> GetMultipleAsync(string queryString)
    {
        var query = _container.GetItemQueryIterator<Item>(new QueryDefinition(queryString));

        var results = new List<Item>();
        while (query.HasMoreResults)
        {
            var response = await query.ReadNextAsync();
            results.AddRange(response.ToList());
        }

        return results;
    }

    public async Task UpdateAsync(string id, Item item)
    {
        await _container.UpsertItemAsync(item, new PartitionKey(id));
    }
} 

Replace Program.cs

Replace Program.cs class with the code shown below:

using CosmosDemo.Services;
using System.Configuration;

class Program
{
    private static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Add services to the container.
        builder.Services.AddControllers();
        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();

        var cosmosDbSection = builder.Configuration.GetSection("CosmosDb");
        var cosmosDbService = InitializeCosmosClientInstanceAsync(cosmosDbSection)
                                .GetAwaiter().GetResult();
        builder.Services.AddSingleton<ICosmosDbService>(cosmosDbService);

        var app = builder.Build();

        // Configure the HTTP request pipeline.
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }

        app.UseHttpsRedirection();

        app.UseAuthorization();

        app.MapControllers();

        app.Run();
    }

    private static async Task<CosmosDbService> InitializeCosmosClientInstanceAsync(IConfigurationSection configurationSection)
    {
        var databaseName = configurationSection["DatabaseName"];
        var containerName = configurationSection["ContainerName"];
        var account = configurationSection["Account"];
        var key = configurationSection["Key"];

        var client = new Microsoft.Azure.Cosmos.CosmosClient(account, key);
        var database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
        await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");

        var cosmosDbService = new CosmosDbService(client, databaseName, containerName);
        return cosmosDbService;
    }
}

Add ItemsController

In the Controllers folder create a class ItemsController as shown below:

using CosmosDemo.Models;
using CosmosDemo.Services;
using Microsoft.AspNetCore.Mvc;

namespace CosmosDemo.Controllers;

[ApiController]
[Route("api/[controller]")]
public class ItemsController : ControllerBase
{
    private readonly ICosmosDbService _cosmosDbService;

    public ItemsController(ICosmosDbService cosmosDbService)
    {
        _cosmosDbService = cosmosDbService ?? 
        throw new ArgumentNullException(nameof(cosmosDbService));
    }

    // GET api/items
    [HttpGet]
    public async Task<IActionResult> List()
    {
        return Ok(await _cosmosDbService.GetMultipleAsync("SELECT * FROM c"));
    }

    // GET api/items/5
    [HttpGet("{id}")]
    public async Task<IActionResult> Get(string id)
    {
        return Ok(await _cosmosDbService.GetAsync(id));
    }

    // POST api/items
    [HttpPost]
    public async Task<IActionResult> Create([FromBody] Item item)
    {
        item.Id = Guid.NewGuid().ToString();
        await _cosmosDbService.AddAsync(item);
        return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
    }

    // PUT api/items/5
    [HttpPut("{id}")]
    public async Task<IActionResult> Edit([FromBody] Item item)
    {
        await _cosmosDbService.UpdateAsync(item.Id, item);
        return NoContent();
    }

    // DELETE api/items/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> Delete(string id)
    {
        await _cosmosDbService.DeleteAsync(id);
        return NoContent();
    }
}

Modify appsettings.json

Replace the contents of appsettings.json file with the one shown below:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "CosmosDb": {
    "Account": "",
    "Key": "",
    "DatabaseName": "DemoDB",
    "ContainerName": "Items"
  }
}

Remove others

You might want to remove weather controller and weather model which was created as part of the template!

Alternatively Download repo

Alternatively, you can download this project from my repository and only add the Account and Key values in appsettings.json, with your values:

https://github.com/ravirammysore/CosmosDemo

Last updated