Blog about tips & tricks for CMS enhancement

eric.petersson

Add CommerceMedia programmatically to Episerver Commerce


Recently a client of ours wanted to make a migration job of importing files from a legacy system into Episerver Commerce instead for handling the media collection suitable for Episerver solutions. Here are some bumps I run into during that process to finalize this task:

Our client's solution was using Commerce 11.8.5 and when fiddling around for solutions why the myEntry.CommerceMediaCollection(myMediaFileReference) was not working, it seemed to be stated here and the solution was to update to latest Commerce, e.g. 13.2x.

After that when migrated the files, the were processed properly in the migration flow but was not visible in the Commerce Catalogue UI for the desired node entry. Strange... and the migrated file into Episerver's media handling said that the file was not in use anywhere. When digging into the log files for this issue I found out "AssetKey is duplicate" - meaning that the database entries had saved the action but not reflected the UI as an asset association.

The solution below was the antidote to process further and get rid of the obscure duplicate entry in the database:

ContentReference migratedFile = new ContentReference(12345);

IAssetContainer content = null;
if (_contentRepository.TryGet(variant.ContentLink, out EntryContentBase entry))
content = (EntryContentBase)entry.CreateWritableClone();

var lightDataCommerceMedia = new CommerceMedia
{
    AssetLink = migratedFile,
    SortOrder = 100
    GroupName = "MyAssetGroupName"
    AssetType = "MyAssetType"
};

content.CommerceMediaCollection.Add(lightDataCommerceMedia);

_contentRepository.Save((IContent)content, SaveAction.Publish | SaveAction.SkipValidation, AccessLevel.NoAccess);

IndexUpdatedVariant(variant);

So by adding the asset and linking it to the media, and then save the reference with either SaveAction.Publish or SaveAction.ForceCurrentVersion, depending on the sitation of new or existing entries, the process was linked properly.

And to finalize the Search & Navigate indexing so that the changes was reflected visibly to our visitors, since we present everything from the Search & Navigate index, I had to process each entry's language embedded variant:

public void IndexUpdatedVariant(EntryContentBase variant)
{
    try
    {
        var languages = _contentRepository.GetLanguageBranches<VariationContent>(variant.ContentLink);
        var variants = new List<VariationContent>();

        foreach (var language in languages)
        {
            VariationContent variantLangEntry = language.CreateWritableClone<VariationContent>();
            variants.Add(variantLangEntry);

            _contentRepository.Publish(variantLangEntry, AccessLevel.NoAccess);
        }

        _client.Index(variants);
    }
    catch (Exception ex)
    {
        _log.Error($"Could not index variant in its language context. {ex}");
    }
}

Hopefully you found this article useful if you ended up in the same issues as me.

Happy coding!