Get started with the DotNET Core SDK

Learn how to set up the DotNET Core SDK and how to use example code.

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

Objectives of the get started guide

By the end of this guide you will have:

Requirements

  • A commercetools Project with a configured API Client.
  • .NET Standard 2.1 (or later).

Placeholder values

Example code in this getting started guide uses placeholders that should be replaced with the following values:

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 DotNET Core SDK

PackageReference

Add the following to your .csproj file.

<ItemGroup>
<PackageReference Include="commercetools.Sdk.Api" Version="*" />
<PackageReference Include="commercetools.Sdk.ImportApi" Version="*" />
<PackageReference Include="commercetools.Sdk.MLApi" Version="*" />
<PackageReference Include="commercetools.Sdk.HistoryApi" Version="*" />
</ItemGroup>

This has been configured to install the latest version of each SDK. To use a specific version, replace * with the version number.

Other installation methods can be viewed at NuGet Gallery.

commercetools.Sdk.Api is required for the Composable Commerce HTTP API. commercetools.Sdk.ImportApi (Import API), commercetools.Sdk.MLApi (Machine Learning API), and commercetools.Sdk.HistoryApi (Change History API) are only needed for more specific use cases.

Set up the client

Add the following code to your Program:

// The following imports are required:
// using commercetools.Sdk.Api;
// using commercetools.Sdk.Api.Client;
// using Microsoft.Extensions.Configuration;
// using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("MyClient:ApiBaseAddress", "https://api.{region}.commercetools.com/"),
new KeyValuePair<string, string>("MyClient:AuthorizationBaseAddress", "https://auth.{region}.commercetools.com/"),
new KeyValuePair<string, string>("MyClient:ClientId", "{clientID}"),
new KeyValuePair<string, string>("MyClient:ClientSecret", "{clientSecret}"),
new KeyValuePair<string, string>("MyClient:ProjectKey", "{projectKey}"),
new KeyValuePair<string, string>("MyClient:Scope", "{scope}")
})
.Build();
services.UseCommercetoolsApi(configuration, "MyClient");
services.AddLogging();
var serviceProvider = services.BuildServiceProvider();
var projectApiRoot = serviceProvider.GetService<ProjectApiRoot>();

projectApiRoot can now be used to build requests to the Composable Commerce API. The following code makes an API call that gets your Project and assigns it to themyProject variable. The Project's name is then output to the console using myProject.Name.

// Make a call to get the Project
var myProject = projectApiRoot
.Get()
.ExecuteAsync()
.Result;
// Output the Project name
Console.WriteLine(myProject.Name);

Using the DotNET SDK

Imports

Without importing resource-specific types/namespaces you will be unable to use specific objects and methods.

For example, to create a Customer you must import:

using commercetools.Sdk.Api.Models.Products;

If not imported, a "The type or namespace name '{name}' could not be found." error is displayed and your program will not run.

Code examples within this guide display commented-out imports, where necessary.

Using builders

The DotNET Core SDK follows a builder pattern when constructing drafts, update actions, and other objects/types that contain multiple fields.

// The following imports are required:
// 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 Category
CategoryDraft categoryDraft = new CategoryDraft()
{
Name = new LocalizedString() { { "en", "english name" } },
Slug = new LocalizedString() { { "en", "english-slug" } },
Key = "category-key"
};

Consult the HTTP API reference to ensure that all required fields are included.

How to structure your API call

Add an endpoint

An endpoint should be added to projectApiRoot. The following targets the Customers endpoint:

var customerInfo = projectApiRoot
.Customers()
// ...

If your IDE supports auto-complete, the full list of endpoints can be viewed.

Screenshot of autocomplete for endpoint

If no endpoint is specified, the Project is referenced.

Retrieving 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 Customer by ID
var customerInfo = projectApiRoot
.Customers()
.WithId("a-customer-id")
.Get()
.ExecuteAsync()
.Result;
// Get a specific Customer by key
var customerInfo = projectApiRoot
.Customers()
.WithKey("a-customer-key")
.Get()
.ExecuteAsync()
.Result;

If you query a resource with an id or key that does not exist, your program will crash with a 404 Not Found error.

In this example, customerInfo now contains the data of the specified Customer. Individual information can be accessed from the fields within that object:

Screenshot of autocomplete for Customer object

Get multiple resources

If no ID or key is included, then the endpoint returns a PagedQueryResponse, which is identical to the PagedQueryResults in the HTTP API.

// Return a ICustomerPagedQueryResponse
var customersQuery = projectApiRoot
.Customers()
.Get()
.ExecuteAsync()
.Result;

The results of these calls can be altered 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

Viewing results

A list of resources within a PagedQueryResponse can be accessed using Results:

// Return a ICustomerPagedQueryResponse
var customersQuery = projectApiRoot
.Customers()
.Get()
.ExecuteAsync()
.Result;
// Put the returned Customers in a list
var listOfCustomers = customersQuery.Results;
// Output the first Customer's email address
Console.WriteLine(listOfCustomers[0].Email);

Writing a resource

Creating a new resource

Creating a new resource requires a draft of the resource to create. For Customers this would be a CustomerDraft, for Products a ProductDraft. These drafts are created using builders.

// The following import is required:
// using commercetools.Sdk.Api.Models.Products;
// Build a CustomerDraft with the required fields (email address and password)
var newCustomerDetails = new CustomerDraft()
{
Email = "dotnet-sdk@example.com",
Password = "password"
};

newCustomerDetails should be included within Post() and followed by ExecuteAsync().

// Post the CustomerDraft and get the new Customer
var newCustomer = projectApiRoot
.Customers()
.Post(newCustomerDetails)
.ExecuteAsync()
.Result
// As creating a Customer returns a CustomerSignInResult, .Customer is required to get the new Customer object
.Customer;

Updating an existing resource

Updating an existing resource requires posting an update payload. This payload (in the case of Customers, a CustomerUpdate) contains a collection of update actions and the last seen version of the resource.

Update actions and payloads are created using builders.

// The following import is required:
// using commercetools.Sdk.Api.Models.Customers;
// Build a CustomerUpdate with the required fields (version and list of ICustomerUpdateActions)
var customerUpdate = new CustomerUpdate()
{
Version = 1,
Actions = new List<ICustomerUpdateAction>
{
{
new CustomerSetKeyAction(){Key="a-unique-customer-key"}
}
}
};

This payload must then be posted to a single resource (using WithId() or WithKey()).

// Post the CustomerUpdate and return the updated Customer
var updatedCustomer = projectApiRoot
.Customers()
.WithId("{customerID")
.Post(customerUpdate)
.ExecuteAsync()
.Result;

Try our example code

The following example code covers some basic operations and is intended to provide you with an insight into how to create, query, and modify entities.

This code can be easily adapted and built upon to help you learn how to use the DotNET SDK to interact with your commercetools Project.

Manage Customers

Create a Customer

C# code for creating a CustomerC#
// The following import is required:
// using commercetools.Sdk.Api.Models.Customers;
// Create a CustomerDraft with the required fields (email address and password)
var newCustomerDetails = new CustomerDraft()
{
Email = "dotnet-sdk@example.com",
Password = "password"
};
// Post the CustomerDraft and get the new Customer
var customer = projectApiRoot
.Customers()
.Post(newCustomerDetails)
.ExecuteAsync()
.Result
.Customer;
// Output the Customer ID
Console.WriteLine(customer.Id);

This example code outputs the ID of the new Customer. Take note of this Customer ID and use it in place of {customerID} in following examples.

Query a Customer

Your new Customer can be queried by adding WithId("{customerID}") after the Customers() endpoint:

C# code for querying a CustomerC#
// Get a Customer by their ID
var queryCustomer = projectApiRoot
.Customers()
.WithId("{customerID}")
.Get()
.ExecuteAsync()
.Result;
// Output the Customer's email address
var customerEmail = queryCustomer.Email;
Console.WriteLine(customerEmail);

Add a Customer name

The required update actions for changing a Customer's name are Set First Name and Set Last Name.

The current version of the Customer is also required.

The version of a new Customer is 1. This value is incremented every time an update action is applied to the Customer.

If the specified version does not match the current version, the request returns an error.

C# code for setting a Customer's first and last namesC#
// The following import is required:
// using commercetools.Sdk.Api.Models.Customers;
// Create a list of update actions and add the setFirstName and setLastName actions
var updateActions = new List<ICustomerUpdateAction>
{
new CustomerSetFirstNameAction()
{
FirstName="John"
},
new CustomerSetLastNameAction()
{
LastName="Smith"
}
};
// Create the CustomerUpdate with the current version of the Customer and the list of update actions
var customerUpdate = new CustomerUpdate()
{
Version = 1,
Actions = updateActions
};
// Post the CustomerUpdate and return the updated Customer
var customerToUpdate = projectApiRoot
.Customers()
.WithId("{customerID}")
.Post(customerUpdate)
.ExecuteAsync()
.Result;
// Output the updated Customer's full name
var updatedCustomerName = customerToUpdate.FirstName + " " + customerToUpdate.LastName;
Console.WriteLine(updatedCustomerName);

Find a Customer by their email address

As the email of a Customer is unique, it is a dependable way to find a Customer.

Customers can be found by their email address by querying the Customers endpoint with a where parameter.

In the commercetools API, where uses a Query Predicate.

C# code for finding a Customer by email addressC#
// Search for Customers whose email address matches the Query Predicate
var customerToFind = projectApiRoot
.Customers()
.Get()
.WithWhere(@$"email=""dotnet-sdk@example.com""")
.ExecuteAsync()
.Result;
// Output the Customer's details. As email addresses must be unique, the first value of the results (0) should be accurate
var customerID = customerToFind.Results[0].Id;
Console.WriteLine(customerID);

If there is no Customer with the specified email address, then a zero-length list is contained in customerToFind.Results.

Manage Products

Creating Products requires more steps than creating Customers. This is due to how Products are modeled in commercetools.

Before a Product can be created, you must first create a ProductType.

Create a ProductType

When creating ProductTypes using the HTTP API, a ProductTypeDraft must be created and posted to the ProductTypes endpoint.

The ProductTypeDraft has two required fields: name and description.

C# code for creating a ProductTypeC#
// The following import is required:
// using commercetools.Sdk.Api.Models.ProductTypes;
// Create a ProductTypeDraft with the required fields (name and description)
var newProductTypeDetails = new ProductTypeDraft()
{
Name = "The name of your ProductType",
Description = "The description of your ProductType"
};
// Post the ProductTypeDraft
var productType = projectApiRoot
.ProductTypes()
.Post(newProductTypeDetails)
.ExecuteAsync()
.Result;
// Output the ProductType ID
var productTypeID = productType.Id;
Console.WriteLine(productTypeID);

This example code outputs the ID of the new Product Type. Take note of this Product Type ID and use it in place of {productTypeID} in following examples.

Create a Product

When creating Products using the HTTP API, a ProductDraft must be created and posted to the Products endpoint.

The ProductDraft has three required fields: name, slug, and productType.

C# code for creating a ProductC#
// The following imports are required:
// using commercetools.Sdk.Api.Models.Products;
// using commercetools.Sdk.Api.Models.ProductTypes;
// using commercetools.Sdk.Api.Models.Common;
// Create a ProductDraft with the required fields (name, slug, and productType)
var newProductDetails = new ProductDraft()
{
Name = new LocalizedString
{
{ "en", "English name for your Product" },
{ "de", "German name for your Product" }
},
Slug = new LocalizedString
{
{ "en", "human-readable-url-for-english-product" },
{ "de", "human-readable-url-for-german-product" }
},
ProductType = new ProductTypeResourceIdentifier()
{
Id = "{productTypeID}"
}
};
// Post the ProductDraft and get the new Product
var product = projectApiRoot
.Products()
.Post(newProductDetails)
.ExecuteAsync()
.Result;
// Output the Product ID
var productID = product.Id;
Console.WriteLine(productID);

Query your Product

Your new Product can be queried by adding WithId("{productID}") after the Products() endpoint:

C# code for querying a ProductC#
// Get a Product by its ID
var queryProduct = projectApiRoot
.Products()
.WithId("{productID}")
.Get()
.ExecuteAsync()
.Result;
// Output the Product's version
Console.WriteLine(queryProduct.Version);

Add a Product key

Adding a key to a Product requires the Set Key update action.

The current version of the Product is also required.

The version of a new Product is 1. This value is incremented every time an update action is applied to the Product.

If the specified version does not match the current version, the request returns an error.

C# code for updating a ProductC#
// The following import is required:
// using commercetools.Sdk.Api.Models.Products;
// Create an list of update actions and add the setKey action
var updateActions = new List<IProductUpdateAction>
{
new ProductSetKeyAction()
{
Key="new-product-key"
}
};
// Create the ProductUpdate with the current version of the Product and the update actions
var productUpdate = new ProductUpdate()
{
Version = 1,
Actions = updateActions
};
// Post the ProductUpdate and return the updated Product
var productToUpdate = projectApiRoot
.Products()
.WithId("{productID}")
.Post(productUpdate)
.ExecuteAsync()
.Result;
// Output the updated Product's key
var updatedProductKey = productToUpdate.Key;
Console.WriteLine(updatedProductKey);

Return a Product by its Key

Your new Product key can be queried by adding WithKey(productKey) after the Products() endpoint:

C# code for querying a Product by its keyC#
// Get a Product by its Key
var findProductByKey = projectApiRoot
.Products()
.WithKey("{productKey}")
.Get()
.ExecuteAsync()
.Result;
// Output the Product's current English name
var productName = findProductByKey.MasterData.Current.Name["en"];
Console.WriteLine(productName);