.NET SDK
The .NET SDK provides a C# interface for interacting with Terragnos Core. It targets .NET 8+ and is distributed via NuGet.
Installation
Package Manager
Install-Package Terragnos.AdminSdk
.NET CLI
dotnet add package Terragnos.AdminSdk
PackageReference
<PackageReference Include="Terragnos.AdminSdk" Version="1.0.0" />
Requirements
- .NET 8.0 or later
System.Net.Http(included)
Basic Usage
Creating a Client
using Terragnos.AdminSdk;
var client = new TerragnosAdminClient(
baseUrl: "https://core.example.com/v1",
token: Environment.GetEnvironmentVariable("TERRAGNOS_TOKEN")
);
Using Statement
The client implements IAsyncDisposable:
await using var client = new TerragnosAdminClient(
baseUrl: "https://core.example.com/v1",
token: token
);
Listing Objects
var result = await client.ListObjectsAsync(
typeId: "traffic-signal",
limit: 25
);
Console.WriteLine($"Found {result.Items.Count} objects");
foreach (var obj in result.Items)
{
Console.WriteLine($"{obj.PublicId}: {obj.TypeId}");
}
Creating Objects
var newObject = await client.CreateObjectAsync(new CreateObjectRequest
{
TypeId = "traffic-signal",
Attributes = new Dictionary<string, object>
{
{ "signalType", "standard" },
{ "intersectionId", "INT-001" }
},
Geometry = new Geometry
{
Type = "Point",
Coordinates = new[] { 19.04, 47.49 }
}
});
Console.WriteLine($"Created object: {newObject.Id}");
Updating Objects
var updated = await client.UpdateObjectAsync(
objectId: "object-id",
version: 1, // Optimistic locking
attributes: new Dictionary<string, object>
{
{ "signalType", "pedestrian" }
}
);
Workflow Transitions
await client.TransitionWorkflowAsync(
objectId: "object-id",
targetState: "approved",
metadata: new Dictionary<string, object>
{
{ "reason", "Meets all requirements" }
}
);
Query Service
var queryResult = await client.RunQueryAsync(new ExecuteQueryRequest
{
Filters = new[]
{
new QueryFilter
{
Field = "typeId",
Operator = "equals",
Value = "traffic-signal"
},
new QueryFilter
{
Field = "attributes.status",
Operator = "equals",
Value = "active"
}
},
Sorts = new[]
{
new QuerySort
{
Field = "createdAt",
Order = "desc"
}
},
Limit = 50
});
Error Handling
try
{
var obj = await client.GetObjectAsync("object-id");
}
catch (TerragnosException ex)
{
switch (ex.StatusCode)
{
case 401:
Console.Error.WriteLine("Authentication failed");
break;
case 403:
Console.Error.WriteLine("Permission denied");
break;
case 404:
Console.Error.WriteLine("Object not found");
break;
case 409:
Console.Error.WriteLine("Optimistic locking conflict");
break;
default:
Console.Error.WriteLine($"API error: {ex.Message}");
break;
}
}
Custom HttpClient
Inject your own HttpClient for custom configuration:
var httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(30)
};
var client = new TerragnosAdminClient(
baseUrl: "https://core.example.com/v1",
token: token,
httpClient: httpClient
);
Available Operations
View all available operations:
foreach (var operation in TerragnosAdminClient.AvailableOperations)
{
Console.WriteLine(operation);
}
Dependency Injection
Register the client in your DI container:
services.AddSingleton<TerragnosAdminClient>(provider =>
{
var config = provider.GetRequiredService<IConfiguration>();
return new TerragnosAdminClient(
baseUrl: config["Terragnos:BaseUrl"],
token: config["Terragnos:Token"]
);
});
Best Practices
- Use async/await – All operations are asynchronous
- Dispose properly – Use
await usingor callDisposeAsync() - Handle exceptions – Always catch
TerragnosException - Reuse clients – Create one client instance per application
- Configure HttpClient – Set appropriate timeouts and retry policies
- Use configuration – Store base URL and token in configuration
- Type safety – Leverage C# types for compile-time safety