Get started with the .NET SDK

Learn how to set up and use the .NET SDK.

Copy for LLM
View as Markdown

This step-by-step guide leads you through setting up and making API calls using the .NET SDK.

Requirements

To follow this guide you should have the following:

  • A commercetools Composable Commerce Project
  • An API Client
  • .NET Standard 2.1 (or later)
For more information on setting up a commercetools Composable Commerce Project or API Client, follow our Getting started with commercetools Composable Commerce guides.

Objectives of the get started guide

By the end of this guide you will have:

Placeholder values

Example code in this guide uses the following placeholder values. You should replace these placeholders with the following values.

If you do not have an API Client, follow our Get your API Client guide.
PlaceholderReplace withFrom
{projectKey}project_keyyour API Client
{clientID}client_idyour API Client
{clientSecret}secretyour API Client
{scope}scopeyour API Client
{region}your RegionHosts

Install the .NET SDK

PackageReference

Add the following to your .csproj file.
<ItemGroup>
  <PackageReference Include="commercetools.Sdk.Api" Version="*" />
</ItemGroup>
You must install commercetools.Sdk.Api to use the HTTP API. To access the Import API, Audit Log API, or Checkout API, include the respective PackageReference within the same <ItemGroup> block:

For Import API

For Audit Log API

For Checkout API

  <PackageReference Include="commercetools.Sdk.ImportApi" Version="*" />
  <PackageReference Include="commercetools.Sdk.HistoryApi" Version="*" />
  <PackageReference Include="commercetools.Sdk.CheckoutApi" Version="*" />
This installs the latest version of each package. To use a specific version, replace * with the version number.

Set up the client

Add the following code to your Program based on the API being accessed.

For HTTP API

For Import API

For Audit Log API

For Checkout API

// Include the following imports:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using commercetools.Sdk.Api;

var services = new ServiceCollection();
var httpApiConfiguration = new ConfigurationBuilder()
  .AddInMemoryCollection(new List<KeyValuePair<string, string>>()
  {
    new KeyValuePair<string, string>("HTTPAPIClient:ApiBaseAddress", "https://api.{region}.commercetools.com/"),
    new KeyValuePair<string, string>("HTTPAPIClient:AuthorizationBaseAddress", "https://auth.{region}.commercetools.com/"),
    new KeyValuePair<string, string>("HTTPAPIClient:ClientId", "{clientID}"),
    new KeyValuePair<string, string>("HTTPAPIClient:ClientSecret", "{clientSecret}"),
    new KeyValuePair<string, string>("HTTPAPIClient:ProjectKey", "{projectKey}")
  })
.Build();

services.UseCommercetoolsApi(httpApiConfiguration, "HTTPAPIClient");
services.AddLogging();

var serviceProvider = services.BuildServiceProvider();
var httpApiRoot = serviceProvider.GetService<commercetools.Sdk.Api.Client.ProjectApiRoot>();

You can now use the httpApiRoot to build requests to the HTTP API.
// Include the following imports:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using commercetools.Sdk.ImportApi;

var services = new ServiceCollection();
var importApiConfiguration = new ConfigurationBuilder()
  .AddInMemoryCollection(new List<KeyValuePair<string, string>>()
  {
    new KeyValuePair<string, string>("ImportAPIClient:ApiBaseAddress", "https://import.{region}.commercetools.com/"),
    new KeyValuePair<string, string>("ImportAPIClient:AuthorizationBaseAddress", "https://auth.{region}.commercetools.com/"),
    new KeyValuePair<string, string>("ImportAPIClient:ClientId", "{clientId}"),
    new KeyValuePair<string, string>("ImportAPIClient:ClientSecret", "{clientSecret}"),
    new KeyValuePair<string, string>("ImportAPIClient:ProjectKey", "getting-started-project")
  })
.Build();

services.UseCommercetoolsImportApi(importApiConfiguration, "ImportAPIClient");
services.AddLogging();

var serviceProvider = services.BuildServiceProvider();
var importApiRoot = serviceProvider.GetService<commercetools.Sdk.ImportApi.Client.ProjectApiRoot>();

You can now use the importApiRoot to build requests to the Import API.
// Include the following imports:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using commercetools.Sdk.HistoryApi;

var services = new ServiceCollection();
var historyApiConfiguration = new ConfigurationBuilder()
  .AddInMemoryCollection(new List<KeyValuePair<string, string>>()
  {
    new KeyValuePair<string, string>("HistoryAPIClient:ApiBaseAddress", "https://history.{region}.commercetools.com/"),
    new KeyValuePair<string, string>("HistoryAPIClient:AuthorizationBaseAddress", "https://auth.{region}.commercetools.com/"),
    new KeyValuePair<string, string>("HistoryAPIClient:ClientId", "{clientId}"),
    new KeyValuePair<string, string>("HistoryAPIClient:ClientSecret", "{clientSecret}"),
    new KeyValuePair<string, string>("HistoryAPIClient:ProjectKey", "getting-started-project")
  })
.Build();

services.UseCommercetoolsHistoryApi(historyApiConfiguration, "HistoryAPIClient");
services.AddLogging();

var serviceProvider = services.BuildServiceProvider();
var historyApiRoot = serviceProvider.GetService<commercetools.Sdk.HistoryApi.Client.ProjectApiRoot>();

You can now use the historyApiRoot to build requests to the Audit Log API.
// Include the following imports:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using commercetools.Sdk.CheckoutApi;

var services = new ServiceCollection();
var checkoutApiConfiguration = new ConfigurationBuilder()
  .AddInMemoryCollection(new List<KeyValuePair<string, string>>()
  {
    new KeyValuePair<string, string>("CheckoutAPIClient:ApiBaseAddress", "https://checkout.{region}.commercetools.com/"),
    new KeyValuePair<string, string>("CheckoutAPIClient:AuthorizationBaseAddress", "https://auth.{region}.commercetools.com/"),
    new KeyValuePair<string, string>("CheckoutAPIClient:ClientId", "{clientId}"),
    new KeyValuePair<string, string>("CheckoutAPIClient:ClientSecret", "{clientSecret}"),
    new KeyValuePair<string, string>("CheckoutAPIClient:ProjectKey", "getting-started-project")
  })
.Build();

services.UseCommercetoolsCheckoutApi(checkoutApiConfiguration, "CheckoutAPIClient");
services.AddLogging();

var serviceProvider = services.BuildServiceProvider();
var checkoutApiRoot = serviceProvider.GetService<commercetools.Sdk.CheckoutApi.Client.ProjectApiRoot>();

You can now use the checkoutApiRoot to build requests to the Checkout API.

Test the Client

The following code contains test calls which outputs to the log.

For HTTP API

For Import API

For Audit Log API

For Checkout API

// Make a call to get the Project
var myProject = await httpApiRoot
  .Get()
  .ExecuteAsync();

// Output the Project name
Console.WriteLine(myProject.Name);
// Make a get call to retrieve a list of ImportContainers
var importContainers = await importApiRoot
  .ImportContainers()
  .Get()
  .ExecuteAsync();

// Output the Import Containers count
Console.WriteLine($"Import containers count: {importContainers.Results.Count}");
// Example call to return recent Category history
var historyEntries = await historyApiRoot
.WithResourceType("categories")
  .Get()
  .ExecuteAsync();

// Output the number of history entries
Console.WriteLine($"History entries count: {historyEntries.Results.Count}");
// Example call to return a Transaction by Key
var transaction = await checkoutApiRoot
  .Transactions()
  .WithKey("a-transaction-key")
  .Get()
  .ExecuteAsync();

// Output the number of items in the Transaction
Console.WriteLine($"Transaction items: {transaction.TransactionItems.Count}");

Use the .NET SDK

Imports

Without importing resource-specific types/namespaces you cannot use specific objects and methods.

For example, to create a Shopping List you must import:

using commercetools.Sdk.Api.Models.ShoppingLists;
If not imported, the SDK returns the The type or namespace name '{name}' could not be found. error and your program will not run.
When using the Import API, Audit Log API, or Checkout API, take care when importing resources as some resources share names in different packages. For example, the HTTP API, Import API, and Audit Log API all have an Asset type. Always use API-specific resources to avoid errors and conflicts.

Create objects

The .NET SDK uses C# object and collection initializer syntax to construct drafts, update actions, and other objects with multiple fields.

// Include the following imports:
// using commercetools.Sdk.Api.Models.Categories;
// using commercetools.Sdk.Api.Models.Common;

// Create a LocalizedString
LocalizedString multiLanguageString = new LocalizedString(){
  {"en", "English value"},
  {"de", "German value"}
};

// Create US$100.00
Money money = new Money()
{
  CurrencyCode = "USD",
  CentAmount = 10000
};

// Create a CategoryDraft
CategoryDraft categoryDraft = new CategoryDraft()
{
  Name = new LocalizedString() { { "en", "english name" } },
  Slug = new LocalizedString() { { "en", "english-slug" } },
  Key = "category-key"
};
Consult the API reference for the HTTP API, Import API, Audit Log API, and Checkout API to ensure that you include all required fields.

Structure your API call

Add an endpoint

Add an endpoint to httpApiRoot. The following targets the Shopping Lists endpoint:
var shoppingListInfo = httpApiRoot
  .ShoppingLists()
  // ...

If your IDE supports auto-complete, you can see the full list of endpoints.

Screenshot of autocomplete for endpoint
If you do not specify an endpoint, the SDK references the Project.

Retrieve data

Get a single resource

When targeting a specific resource, you should include its ID or key followed by Get(), ExecuteAsync(), and Result.
// Get a specific Shopping List by ID
var shoppingListInfo = httpApiRoot
  .ShoppingLists()
  .WithId("a-shoppinglist-id")
  .Get()
  .ExecuteAsync()
  .Result;

// Get a specific Shopping List by key
var shoppingListInfo = httpApiRoot
  .ShoppingLists()
  .WithKey("a-shoppinglist-key")
  .Get()
  .ExecuteAsync()
  .Result;
If you query a resource with an id or key that does not exist, your program will crash with a Not Found error.
In this example, shoppingListInfo now contains the data of the specified Shopping List. You can access information from the fields within that object:
Screenshot of autocomplete for ShoppingList object

Get multiple resources

If you do not include an ID or key, the endpoint returns a PagedQueryResponse, which is identical to PagedQueryResults in the HTTP API.
// Return an IShoppingListPagedQueryResponse
var shoppingListsQuery = httpApiRoot
  .ShoppingLists()
  .Get()
  .ExecuteAsync()
  .Result;
You can alter the results of these calls by including WithWhere(), WithSort(), WithExpand(), WithLimit(), or WithOffset() after Get().
These are identical to the parameters you can add to standard HTTP API calls. If your IDE supports autocomplete you can view a full list of methods available:
Screenshot of autocomplete for parameters

Use the Query Predicate builder

For querying results you can also use the type safe Query Predicate builders. They allow you to programmatically create a Query Predicate using the withQuery method.
// Return all Customers that have not verified their email address
var response = httpApiRoot
 .Customers()
 .Get()
 .WithQuery(c => c.IsEmailVerified().Is(false))
 .ExecuteAsync()
 .Result;
You can find more example usage of Query Predicate builders on GitHub.

View results

You can access the list of resources within a PagedQueryResponse using Result:
// Return an IShoppingListPagedQueryResponse
var shoppingListsQuery = httpApiRoot
  .ShoppingLists()
  .Get()
  .ExecuteAsync()
  .Result;

// Put the returned Shopping Lists in a list
var listOfShoppingLists = shoppingListsQuery.Results;

// Output the first Shopping List's English name
Console.WriteLine(listOfShoppingLists[0].Name["en"]);

Write a resource

Create a new resource

Creating a new resource requires a draft of the resource to create. For Shopping Lists this is a ShoppingListDraft. You create these drafts using builders.
// Build a ShoppingListDraft with the required fields (name)
var newShoppingListDetails = new ShoppingListDraft()
{
  Name = new LocalizedString() { { "en", "English name of Shopping List" } }
};
Include newShoppingListDetails within Post() and follow it with ExecuteAsync().
// Post the ShoppingListDraft and get the new Shopping List
var newShoppingList = httpApiRoot
  .ShoppingLists()
  .Post(newShoppingListDetails)
  .ExecuteAsync()
  .Result;

Update an existing resource

Updating an existing resource requires posting an update payload. This payload (in the case of Shopping Lists, a ShoppingListUpdate) contains a collection of update actions and the last seen version of the resource.
You can create update actions and payloads by using builders.
// Build a ShoppingListUpdate with the required fields (version and list of IShoppingListUpdateActions)
var shoppingListUpdate = new ShoppingListUpdate()
{
  Version = 1,
  Actions = new List<IShoppingListUpdateAction>
  {
    {
      new ShoppingListSetKeyAction(){Key="a-new-shoppinglist-key"}
    }
  }
};
You can then post the payload to a single resource (using WithId() or WithKey()).
// Post the ShoppingListUpdate and return the updated Shopping List
var updatedShoppingList = httpApiRoot
  .ShoppingLists()
  .WithId("{shoppingListID}")
  .Post(shoppingListUpdate)
  .ExecuteAsync()
  .Result;

Delete a resource

Deleting a resource requires using the .Delete() method with the last seen version of the resource. You must identify the resource to delete using WithId() or WithKey().
// Delete and return a Shopping List
var deletedShoppingList = httpApiRoot
  .ShoppingLists()
  .WithId("{shoppingListID}")
  .Delete()
  .WithVersion(1)
  .WithDataErasure(true) // Include to erase related personal data
  .ExecuteAsync()
  .Result;

Use GraphQL

With the help of ZeroQL you can generate a type safe query and projection client. The results are then mapped to the correct response type.

The response types will have all available fields defined by the selector.

var variables = new { productFilter = $@"id = ""{productId}""" };
var response = await client.Query(variables,
  static (i, o) => o.Products(where: i.productFilter,
      selector: r => new { results = r.Results(product => new { product.Id })}
  )
);

Assert.NotNull(response.Data?.results[0].Id);

Next steps

Continue learning about the .NET SDK by checking our SDK code examples. You will find example code for creating, querying, and updating Customers and Products.
The Me Endpoint Checkout app demonstrates how to use the Me endpoints to create an example web store.