In this guide, we'll use Umbraco as a Digital Asset Management system and integrate it with Ucommerce. We'll use the Umbraco Media Delivery API to retrieve the information we need.
To make Ucommerce communicate with Umbraco, we need a client to handle the REST calls to the Umbraco Delivery API. You can either code this yourself or use a tool to generate it. For this guide, we're going to use Microsoft Kiota to generate it for us.
In the Ucommerce project, create a new class UmbracoImageService that inherits from IImageService. This class is responsible for mapping between the UmbracoClient created previously and Ucommerce. See Images for more details.
Below is a complete example:
usingSystem.Collections.Immutable;usingUcommerce.Web.Infrastructure;usingUcommerce.Web.Infrastructure.Core;usingUcommerce.Web.Infrastructure.Core.Models;usingUcommerceTest.Integrations.Umbraco;usingUcommerceTest.Integrations.Umbraco.Models;namespaceUcommerceTest;publicclassUmbracoImageService(UmbracoClient kiotaClient,UmbracoSettings umbracoSettings) :IImageService{publicasyncTask<IImmutableList<Content>> Get(string? parentId =null,int startAt =0,int limit =30,CancellationToken? token =null) { parentId ??="/";var items =awaitkiotaClient.Umbraco.Delivery.Api.V2.Media.GetAsync( request => {request.QueryParameters.Fetch=$"children:{parentId}";request.QueryParameters.Skip= startAt;request.QueryParameters.Take= limit; },token.GetValueOrDefault());returnitems?.Items? .Select(item =>MapMedia(parentId, item)) .ToImmutableList() ??ImmutableList<Content>.Empty; }publicasyncTask<Content> GetById(string? id,CancellationToken token) {if (string.IsNullOrEmpty(id)) {returnImageNotFound(); }var item =awaitkiotaClient.Umbraco.Delivery.Api.V2.Media.Item[Guid.Parse(id)] .GetAsync(cancellationToken: token);return item isnull?ImageNotFound() :MapMedia(null, item); }publicasyncTask<IImmutableList<Content>> GetByIds(IImmutableList<string> ids,CancellationToken? token =null) {var guids =ids.Select(Guid.Parse).Cast<Guid?>().ToArray();var items =awaitkiotaClient.Umbraco.Delivery.Api.V2.Media.Items.GetAsync( request =>request.QueryParameters.Id= guids,token.GetValueOrDefault()) ?? [];return items .Select(item =>MapMedia(null, item)) .ToImmutableList(); } /// <summary> /// Maps the response model to a Content object /// </summary>privateContentMapMedia(string? parentId,ApiMediaWithCropsResponseModel responseModel) =>new() { Name =responseModel.Name??"No name", NodeType = responseModel.MediaType!.Equals("Folder") ? Constants.ImagePicker.Folder : Constants.ImagePicker.Image,
Url = string.IsNullOrWhiteSpace(responseModel.Url) ? "No URL" : CombineUris(umbracoSettings.BaseUrl, responseModel.Url),
Id =responseModel.Id?.ToString() ??"No ID", ParentId = parentId, Icon =responseModel.MediaType!.Equals("Folder") ?"icon-folder":"icon-picture", ChildrenCount =null }; /// <summary> /// Gives a default image when the request image could not be found /// </summary>privatestaticContentImageNotFound() {returnnewContent { Id ="image-not-found", Name ="image-not-found.png", Url ="ImageNotFoundImageURL", NodeType =Constants.ImagePicker.Image }; } /// <summary> /// Combines two URIs into one making sure there is only one '/' between them /// </summary>privatestaticstringCombineUris(string uri1,string uri2) { uri1 =uri1.TrimEnd('/'); uri2 =uri2.TrimStart('/');return$"{uri1}/{uri2}"; }}
Each method is straightforward: Get the necessary data from Umbraco using the UmbracoClient, map the data to fit Ucommerce, and return the result.
Note that the ChildrenCount is set to null. This is because the Umbraco Delivery API does not contain any information on the number of children for a given node. See Media for more details on what that means.
Tying everything together
The last step needed is to set up UmbracoClient and UmbracoImageService in the Ucommerce project. Because the Umbraco Delivery API does not contain any information on the base URL, we'll have to set that up manually. As you might have noticed, we also need the base URL when mapping the URL as Umbraco returns only relative URLs.
UmbracoSettings.cs
The settings object is a single line of code:
publicrecordUmbracoSettings(string BaseUrl);
UmbracoModuleExtensions.cs
To make the integration reusable, we suggest using an extension method for every module: