Docs Menu
Docs Home
/ / /
C#/.NET
/

Use OData with MongoDB

On this page

  • Overview
  • Sample Data
  • Tutorial
  • Install Dependencies
  • Define your Models
  • Create an OData Controller
  • Configure the OData Service
  • Run the Application
  • Query the Data
  • Additional Information

OData (Open Data Protocol) is a standardized protocol for building and consuming RESTful APIs that allows for the querying and manipulation of data by using HTTP requests. It provides a uniform way to expose and interact with data from multiple sources.

In this tutorial, you will learn how to integrate OData with your MongoDB application.

This tutorial uses the sample_restaurants.restaurants collection from the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the Quick Start.

1

Create a new ASP.Net application named ODataExample and install the .NET/C# Driver. You can install the driver by using the NuGet package manager in your IDE, or by running the following command in the .NET CLI:

dotnet add package MongoDB.Driver

Then, install the MongoDB.AspNetCore.OData NuGet package through the NuGet Package Manager or through the .NET CLI by running the following command:

dotnet add package MongoDB.AspNetCore.OData
2

Create a new folder in your solution called Models and copy the following Restaurant.cs, Address.cs, and GradeEntry.cs files into the folder:

public class Restaurant
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; }
[BsonElement("restaurant_id")]
public string RestaurantId { get; set; }
public string Cuisine { get; set; }
public Address Address { get; set; }
public string Borough { get; set; }
public List<GradeEntry> Grades { get; set; }
}
public class Address
{
public string Building { get; set; }
[BsonElement("coord")]
public double[] Coordinates { get; set; }
public string Street { get; set; }
[BsonElement("zipcode")]
public string ZipCode { get; set; }
}
public class GradeEntry
{
public DateTime Date { get; set; }
public string Grade { get; set; }
public float? Score { get; set; }
}

Note

The documents in the restaurants collection use the snake-case naming convention. The examples in this guide use a ConventionPack to deserialize the fields in the collection into Pascal case and map them to the properties in the Restaurant class.

To learn more about custom serialization, see Custom Serialization.

3

Create a new folder in your solution called Controllers and add a new controller file called RestaurantsController.cs. Copy the following code into the file:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Routing.Controllers;
using MongoDB.AspNetCore.OData;
using MongoDB.Driver;
using ODataTest.Models;
namespace ODataTest.Controllers;
public class RestaurantsController : ODataController
{
private readonly IQueryable<Restaurant> _restaurants;
public RestaurantsController(IMongoClient client)
{
var database = client.GetDatabase("sample_restaurants");
_restaurants = database.GetCollection<Restaurant>("restaurants")
.AsQueryable();
}
// Registers Get endpoint and sets max documents to 5
[MongoEnableQuery(PageSize = 5)]
public ActionResult<IEnumerable<Restaurant>> Get()
{
return Ok(_restaurants);
}
}

This code performs the following actions:

  • Creates a constructor that connects to MongoDB, and gets the restaurants collection.

  • Creates a Get endpoint that returns all restaurants in the collection.

  • Specifies the MongoEnableQuery attribute to enable querying on the Get endpoint.

  • Specifies the PageSize attribute on MongoEnableQuery to limit the number of documents returned to 5.

4

Paste the following code into your Program.cs file to configure the OData service and map your controller endpoints.

using Microsoft.AspNetCore.OData;
using Microsoft.OData.ModelBuilder;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Driver;
using ODataTest.Models;
var builder = WebApplication.CreateBuilder(args);
// Registers a convention pack to convert fields to camel case
var camelCaseConvention = new ConventionPack {
new CamelCaseElementNameConvention()
};
ConventionRegistry.Register(
"CamelCase", camelCaseConvention, type => true);
builder.Services.AddSingleton<IMongoClient>(
new MongoClient("<Your connection URI>"));
// Registers the Restaurants entity and sets the Id field as the key
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Restaurant>("Restaurants");
modelBuilder.EntityType<Restaurant>().HasKey(r => r.Id);
// Adds OData and specify query capabilities
builder.Services.AddControllers().AddOData(
options => options.Select()
.AddRouteComponents("odata", modelBuilder.GetEdmModel())
);
var app = builder.Build();
app.UseRouting();
app.MapControllers();
app.Run();

Note

Replace the <"Your connection URI"> placeholder with your MongoDB connection string.

This code performs the following actions:

  • Instantiates a new MongoClient and registers it as a singleton in the dependency injection container.

  • Defines the Entity Data Model (EDM) and registers Restaurants as an entity set with the key Id.

  • Adds the OData service and enables the Select() query operation.

  • Registers the route by using the AddRouteComponents() method.

  • Calls the UseRouting() and MapControllers() methods to match incoming HTTP requests and route them to the appropriate endpoint.

Note

The .NET/C# Driver does not support OData-Aggregation with the $apply query operation.

5

Run the application by using your IDE, or by running the following command in your shell at the root directory of your project:

dotnet run ODataExample.csproj

After running the application, your terminal displays output similar to the following:

info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5183
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: <Path to your project>

Tip

After running your application, your IDE might automatically open a browser window to the URL where the application is running, which displays a "page can't be found" error. This is expected because the application only has a single Get endpoint configured.

6

To query the data, navigate to the Get endpoint specified in the application. To do so, open a browser and navigate to the localhost URL specified in the terminal output from the preceding step. Then, append the route for the Get endpoint: /odata/Restaurants. For example, if an application is running at localhost:5183, navigate to http://localhost:5183/odata/Restaurants.

If successful, the browser displays 5 restaurants in the collection, in JSON format. The output is similar to the following:

{
"@odata.context": "http://localhost:5183/odata/$metadata#Restaurants",
"value": [
{
"Name": "Glorious Food",
"RestaurantId": "40361521",
"Cuisine": "American",
"Borough": "Manhattan",
"Id": "...",
"Address": {
"Building": "522",
"Coordinates": [-73.95171, 40.767461],
"Street": "East 74 Street",
"ZipCode": "10021"
},
"Grades": [
...
]
},
...
]
}

To learn more about ASP.NET Core OData, see the Microsoft OData documentation.

To learn more about OData, see the OData documentation.

Back

Search Geospatially