Connecting a .NET Application to MongoDB
MongoDB is a NoSQL database that is widely used for building modern applications due to its flexibility and scalability. In this blog, we will walk through the process of connecting a .NET application to MongoDB and performing CRUD operations. We'll use the code from a project that manages suggestions for improvements in an application.
Prerequisites
Install .NET SDK
MongoDB installed locally or available through a cloud service such as MongoDB Atlas
MongoDB .NET Driver installed through NuGet
Step 1: Install MongoDB Driver in Your .NET Project
To begin, ensure you have MongoDB.Driver installed in your project. You can do this by running the following command in the terminal:
dotnet add package MongoDB.Driver
This installs the official MongoDB .NET driver, which provides tools to interact with MongoDB.
Step 2: Define the MongoDB Connection Interface
In any well-structured application, it’s good practice to define interfaces for database connections to ensure abstraction and easier maintainability. Here's how the interface for MongoDB connection is structured in this project:
namespace SuggestionAppLibrary.Interfaces
{
public interface IDbConnection
{
string DbName { get; }
string CategoryCollectionName { get; }
string StatusCollectionName { get; }
string UserCollectionName { get; }
string SuggestionCollectionName { get; }
MongoClient Client { get; }
IMongoCollection<CategoryModel> CategoryCollection { get; }
IMongoCollection<StatusModel> StatusCollection { get; }
IMongoCollection<UserModel> UserCollection { get; }
IMongoCollection<SuggestionModel> SuggestionCollection { get; }
}
}
This interface defines key elements such as collection names and the client connection for MongoDB. Each collection in MongoDB will represent a different dataset like Categories, Statuses, Users, and Suggestions.
Step 3: Defining Models with MongoDB BSON Attributes
MongoDB works with documents, and in this application, a suggestion has various fields such as a description, creation date, author, and status.
When working with MongoDB in .NET, you’ll need to create model classes that map to MongoDB collections. MongoDB uses BSON (Binary JSON) as its storage format. To ensure that your C# models map correctly to MongoDB documents, you can use BSON attributes provided by the MongoDB.Bson
library.
Here is the SuggestionModel
that defines how each suggestion is structured:
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
public class SuggestionModel
{
[BsonId] // Marks 'Id' as the document identifier
[BsonRepresentation(BsonType.ObjectId)] // Ensures 'Id' is stored as an ObjectId
public string Id { get; set; }
[BsonElement("suggestionText")] // Maps 'Suggestion' to 'suggestionText' field
public string Suggestion { get; set; }
[BsonElement("description")] // Maps 'Description' to 'description' field
public string Description { get; set; }
[BsonElement("dateCreated")] // Maps 'DateCreated' to 'dateCreated' field
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)] // Ensures date is stored in UTC
public DateTime DateCreated { get; set; } = DateTime.UtcNow;
[BsonElement("category")] // Maps 'Category' to 'category' field
public CategoryModel Category { get; set; }
[BsonElement("author")] // Maps 'Author' to 'author' field
public UserModel Author { get; set; }
[BsonElement("userVotes")] // Maps 'UserVotes' to 'userVotes' field
public HashSet<string> UserVotes { get; set; } = new();
[BsonElement("status")] // Maps 'SuggestionStatus' to 'status' field
public StatusModel SuggestionStatus { get; set; }
[BsonElement("ownerNotes")] // Maps 'OwnerNotes' to 'ownerNotes' field
public string OwnerNotes { get; set; }
[BsonElement("approvedForRelease")] // Maps 'ApprovedForRelease' to 'approvedForRelease' field
public bool ApprovedForRelease { get; set; } = false;
[BsonElement("archived")] // Maps 'Archived' to 'archived' field
public bool Archived { get; set; } = false;
[BsonElement("rejected")] // Maps 'Rejected' to 'rejected' field
public bool Rejected { get; set; } = false;
}
Each field is annotated with BSON attributes to map the C# object to the MongoDB document structure.
Common BSON Properties
[BsonId]
- Marks the property as the document ID. In MongoDB, every document must have a unique identifier, which is commonly the
_id
field.
- Marks the property as the document ID. In MongoDB, every document must have a unique identifier, which is commonly the
[BsonRepresentation(BsonType.ObjectId)]
- This attribute specifies that the
Id
field will be stored as a MongoDB ObjectId type, even though it is represented as a string in the model.
[BsonElement("elementName")]
Maps a property to a specific BSON element (field) in the MongoDB document. The
elementName
parameter represents the field name in the MongoDB document.This is useful if the property name in the model is different from the field name in MongoDB.
[BsonIgnoreIfNull]
- Tells MongoDB to ignore this field if it is
null
. This can help avoid unnecessary storage in the database.
[BsonIgnore]
- Prevents a property from being serialized or deserialized. The field won’t be saved in MongoDB, nor will it be populated when reading documents from MongoDB.
[BsonDateTimeOptions]
- This decorator controls how
DateTime
values are stored in MongoDB. For example, you can specify whether theDateTime
should be treated asUTC
orLocal
.
[BsonDefaultValue(defaultValue)]
- Specifies a default value for a field if it is not set when the document is created.
[BsonRequired]
- Ensures that the field must be present in the document when it is deserialized from MongoDB. If the field is missing, an exception will be thrown.
Step 4: Implementing the Repository Pattern
To ensure proper abstraction, this project uses the repository pattern. A repository for SuggestionModel
is responsible for interacting with the MongoDB collections. Here's a snippet of the SuggestionRepo
class that interacts with the Suggestion
collection:
public class SuggestionRepo : ISuggestion
{
private readonly IMongoCollection<SuggestionModel> _suggestions;
private readonly IMemoryCache _cache;
private const string CacheName = "SuggestionData";
public SuggestionRepo(IDbConnection db, IMemoryCache cache)
{
_suggestions = db.SuggestionCollection;
_cache = cache;
}
public async Task<List<SuggestionModel>> GetAllSuggestions()
{
var cachedSuggestions = _cache.Get<List<SuggestionModel>>(CacheName);
if (cachedSuggestions == null)
{
var suggestions = await _suggestions.FindAsync(s => !s.Archived);
cachedSuggestions = suggestions.ToList();
_cache.Set(CacheName, cachedSuggestions, TimeSpan.FromMinutes(1));
}
return cachedSuggestions;
}
// Additional CRUD methods...
}
This class handles various operations such as retrieving all suggestions, filtering approved suggestions, and caching the data to reduce load on the database.
Step 5: Setting Up MongoDB Configuration
To establish a connection to MongoDB, you will need to configure your application. Typically, this is done in the DbConnection.cs
file, which you provided. Here's an example of how the connection configuration might look:
using Microsoft.Extensions.Configuration;
namespace SuggestionAppLibrary.DataAccess;
public class DbConnection : IDbConnection
{
private readonly IConfiguration _config;
private readonly IMongoDatabase _db;
private string _connectionId = "MongoDb";
public string DbName { get; private set; }
public string CategoryCollectionName { get; private set; } = "categories";
public string StatusCollectionName { get; private set; } = "statuses";
public string UserCollectionName { get; private set; } = "users";
public string SuggestionCollectionName { get; private set; } = "suggestions";
public MongoClient Client { get; private set; }
public IMongoCollection<CategoryModel> CategoryCollection { get; private set; }
public IMongoCollection<StatusModel> StatusCollection { get; private set; }
public IMongoCollection<UserModel> UserCollection { get; private set; }
public IMongoCollection<SuggestionModel> SuggestionCollection { get; private set; }
public DbConnection(IConfiguration config)
{
_config = config;
Client = new MongoClient(_config.GetConnectionString(_connectionId));
DbName = _config["DatabaseName"];
_db = Client.GetDatabase(DbName);
CategoryCollection = _db.GetCollection<CategoryModel>(CategoryCollectionName);
StatusCollection = _db.GetCollection<StatusModel>(StatusCollectionName);
UserCollection = _db.GetCollection<UserModel>(UserCollectionName);
SuggestionCollection = _db.GetCollection<SuggestionModel>(SuggestionCollectionName);
}
}
In this class, the MongoDB client is initialized using a connection string from the configuration file (appsettings.json
), which you can define as follows:
{
"ConnectionStrings": {
"MongoDB": "mongodb://localhost:27017"
},
"DatabaseName": "SuggestionAppDB"
}
Make sure to replace the connection string with your MongoDB instance details.
Step 6: Register Services in the .NET Application
You need to register the services in your Program.cs
or Startup.cs
. This will ensure the repository and database connection services are available throughout the application.
public static class RegisterServices
{
public static void ConfigureServices(this WebApplicationBuilder builder)
{
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddMemoryCache();
// Register MongoDB services
builder.Services.AddSingleton<IDbConnection, DbConnection>();
builder.Services.AddSingleton<ISuggestion, SuggestionRepo>();
}
}
Step 7: Performing CRUD Operations
Now that your application is connected to MongoDB, you can perform CRUD operations. For example, here is how you can retrieve suggestions:
public async Task<List<SuggestionModel>> GetAllSuggestions()
{
var suggestions = await _suggestions.FindAsync(s => !s.Archived);
return suggestions.ToList();
}
And here’s how to insert a new suggestion:
public async Task CreateSuggestion(SuggestionModel suggestion)
{
await _suggestions.InsertOneAsync(suggestion);
}
Conclusion
By following the steps in this guide, you have successfully set up a MongoDB connection in a .NET application and performed basic CRUD operations. This setup allows you to efficiently work with MongoDB and leverage its flexibility in your application development process. You can now expand on this foundation by adding more complex logic or improving your database structure based on your app's requirements.
Subscribe to my newsletter
Read articles from Melah Ghislain directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Melah Ghislain
Melah Ghislain
Full Stack Developer | Building Scalable Applications with Typescript, JavaScript and C# I am a Full Stack Developer with over 3+ years of experience crafting high-quality, user-centric web applications. Proficient in a wide range of technologies, including React, Node.js, C#/.NET, MongoDB, and PostgreSQL, I focus on building scalable and high-performance solutions. My passion lies in creating intuitive user interfaces and optimizing code to deliver seamless user experiences. I enjoy working in Agile environments and collaborating with cross-functional teams to bring innovative ideas to life. I’m fluent in both English and French, and I continuously seek opportunities to learn and contribute to open-source projects. When I'm not coding, I work on personal projects, exploring creative ways to solve real-world problems through technology