Skip to content

kraldev/Dynamics365-BusinessCentral

Repository files navigation

Dynamics365.BusinessCentral

A lightweight, strongly-typed client for the Dynamics 365 Business Central OData API.

✨ Features

  • Typed OData querying with fluent filter composition
  • Built-in OAuth2 client credentials authentication
  • Automatic token caching and refresh
  • Fluent paging, ordering and selection helpers
  • Clean DI integration
  • No runtime dependencies beyond HttpClient and System.Text.Json

📦 Installation

dotnet add package Dynamics365.BusinessCentral

🧩 Dependency Injection

services.AddBusinessCentral(options =>
{
    options.TenantId = "your-tenant-id";
    options.ClientId = "your-client-id";
    options.ClientSecret = "your-client-secret";
    options.Company = "CRONUS AG";
    options.BaseUrl = "https://api.businesscentral.dynamics.com/v2.0/{tenant}/Production/ODataV4";
    options.TokenEndpoint = "https://login.microsoftonline.com/{TenantId}/oauth2/v2.0/token";
    options.Scope = "https://api.businesscentral.dynamics.com/.default";
});

public class MyService
{
    private readonly IBusinessCentralClient _client;

    public MyService(IBusinessCentralClient client)
    {
        _client = client;
    }
}

🔍 Querying

Simple Query

var orders = await client.QueryAsync<Order>("salesOrders");

With Filters

var filter =
    Filter.Equals("Status", "Open")
          .And(Filter.GreaterThan("Amount", 100));

var orders = await client.QueryAsync<Order>("salesOrders", filter);

Paging and Ordering

var orders = await client.QueryAsync<Order>(
    "salesOrders",
    Filter.Equals("Status", "Open"),
    o => o.WithTop(100).OrderByAsc("No"));

Query All

var allOrders = await client.QueryAllAsync<Order>("salesOrders");

Raw Query

var raw = await client.QueryRawAsync<JsonElement>("salesOrders?$top=5");

Patch

await client.PatchAsync(
    "salesOrders",
    "No='1000'",
    new { Status = "Released" });

🧪 Filters

Method Expression
Filter.Equals field eq value
Filter.NotEquals field ne value
Filter.GreaterThan field gt value
Filter.GreaterOrEqual field ge value
Filter.LessThan field lt value
Filter.LessOrEqual field le value
Filter.Contains contains(field,value)
Filter.StartsWith startswith(field,value)
Filter.EndsWith endswith(field,value)
Filter.In field in (...)
Filter.IsNull field eq null
Filter.IsNotNull field ne null

Example

public static class SmokeTestEndpoints
{
    public static void MapSmokeTests(this WebApplication app)
    {
        app.MapGet("/bc/orders", async (IBusinessCentralClient client) =>
        {
            var orders = await client.QueryAsync<dynamic>(
                "LDATProductionOrd1er",
                Filter.Equals("Status", "Released"),
                o => o.WithTop(5));

            return Results.Ok(orders);
        });

        app.MapGet("/bc/orders/all", async (IBusinessCentralClient client) =>
        {
            var orders = await client.QueryAllAsync<dynamic>("salesOrders");
            return Results.Ok(orders.Count);
        });
    }
}

About

A lightweight, strongly-typed client for the Dynamics 365 Business Central OData API.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages