OData for ASP.NET Core 6.0 on Mac via command line
Tags: csharp, dotnet, programming, odata
Published: 2022-01-22 16:29:08

OData is a set of best practices for building and consuming RESTful APIs. ASP.NET Core OData Nuget package provides capabilities for smooth development of OData REST API in .NET application.

I would like to document how I added OData support via the command line since .NET 6.0 includes new structure of Program.cs and I've faced couple challenges there.

Here are the steps that I followed:

### Create ASP.NET Core Web API 6.0 application

```bash
>> dotnet new webapi -o odata
>> cd odata
```

### Add Entity Framework Core and OData package references
I used EF Core In-Memory Database Provider for simplicity.

```bash
>> dotnet add package Microsoft.EntityFrameworkCore.InMemory
>> dotnet add package Microsoft.AspNetCore.Odata
```

### Update `Program.cs`

- OData convention model
- OData controller
- Entity Framework Context

```csharp
using Microsoft.AspNetCore.OData;
using Microsoft.EntityFrameworkCore;
using Microsoft.OData.Edm;
using Microsoft.OData.ModelBuilder;
using OData.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();

// Entity Framework Context
builder.Services.AddDbContext<ODataContext>(opt => opt.UseInMemoryDatabase("Cars"));

// OData convention model and OData controller
builder.Services.AddControllers().AddOData(opt => opt.AddRouteComponents("odata", GetEdmModel()).Filter().Select());

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

IEdmModel GetEdmModel()
{
    var builder = new ODataConventionModelBuilder();
    builder.EntitySet<Car>("Cars");
    return builder.GetEdmModel();
}
```

### Add support for GET requests

We will use `EnableQuery` annotation to enable GET Requests `CarsController.cs`. We use a static class `DataSource` provides the test data. The code for `DataSource.GetCars()` can be found [here](https://github.com/alkondrashov/odata)

```csharp
using Microsoft.AspNetCore.OData.Routing.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using OData.Models;
using OData.Data;

namespace OData.Controllers
{
    public class CarsController : ODataController
    {
        private ODataContext _context;
        private readonly ILogger<CarsController> _logger;

        public CarsController(ODataContext context, ILogger<CarsController> logger) {
            _context = context;
            _logger = logger;

            if (_context.Cars.Count() == 0)
            {
                foreach (var b in DataSource.GetCars())
                {
                    _context.Cars.Add(b);
                }
                _context.SaveChanges();
            }
        }


        [EnableQuery]
        public IActionResult Get()
        {
            return Ok(_context.Cars);
        }

        [EnableQuery]
        public IActionResult Get(int key)
        {
            return Ok(_context.Cars.FirstOrDefault(c => c.Id == key));
        }
    }
}
```

### Run the application and check the result
Good way to prove that OData works is to query all cars where the price is less or equal 50. There is only one car that satisfies that condition.

```bash
>> dotnet run
>> curl -X 'GET' 'https://localhost:7005/odata/Cars?$filter=Price le 50' -H 'accept: text/plain' -k
```

The response should look like the following:

```bash
{
    "@odata.context": "https://localhost:7005/odata/$metadata#Cars",
    "value": [
        {
            "Id": 2,
            "Brand": "BMW",
            "Price": 49.99,
            "Model": "3 Series"
        }
    ]
}
```

## Summary
In this example, we looked at adding support for OData to ASP.NET Core Web API application and performed a simple query to prove that the OData requests are coming through. Hope this helped you run your project.

## Links
- [Code from this example](https://github.com/alkondrashov/odata)
- [Example with OData support for a classic ASP.NET Web application](https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint)
- [Example with OData support for ASP.NET Core 2.0 Web application](https://devblogs.microsoft.com/odata/asp-net-core-odata-now-available/)
- [Example with OData support for ASP.NET Core 5.0 Web application](https://devblogs.microsoft.com/odata/asp-net-odata-8-0-preview-for-net-5/)
- [Another example with OData support for ASP.NET 5.0 Web application](https://referbruv.com/blog/posts/working-with-odata-integrating-an-existing-aspnet-core-3x-api)