---
title: Asset URL resolver
slug: commerce-connect-15/docs/asset-url-resolver
docTags: 
createdAt: 2026-07-30T20:34:43.000Z
---

The functionality is demonstrated in the Optimizely Commerce Connect sample site on the **Assets** tab for catalog content, where users can define a set of assets to display.

`EntryContentBase` and `NodeContent` implements `IAssetContainer`, which contains the property `CommerceMediaCollection`. Content that implements the interface `IAssetContainer` can contain several assets.

You can often define several asset items for a catalog item, but only one is shown on the site. By default, the first item is used in the asset collection in the catalog UI, ordered by the `SortOrder` property. You can change this behavior for content types. Adding a type to the `AssetUrlConventions` class lets you set a default group for the specific content type. Assets in this group are more important than assets in other groups, regardless of sort order.

### GetAssetUrl

The `GetAssetUrl` method gets the default asset for content. `SortOrder` orders the collection of assets. The first item in the list is selected in the specified default group for the content. If there is no default group or asset for the default group, the first item in the list is used.

```csharp
using System.Globalization;
using EPiServer;
using EPiServer.Commerce.Catalog;
using EPiServer.Commerce.Catalog.ContentTypes;
using EPiServer.Commerce.SpecializedProperties;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAccess;
using EPiServer.Security;
using EPiServer.Web;
using Mediachase.Commerce.Catalog;

public class UrlResolverSample {
  private AssetUrlResolver assetUrlResolver;
  private ReferenceConverter referenceConverter;
  private IContentLoader contentLoader;
  private AssetUrlConventions assetUrlConventions;
  private IContentRepository contentRepository;
  private ContentMediaResolver mediaDataResolver;
  private ContentTypeRepository contentTypeRepository;

  public string GetAssetUrl() {
    ContentReference rootCatalogLink;
    //Get a suitable MediaData type from extension
    var mediaType = mediaDataResolver.GetFirstMatching("jpg");
    var contentType = contentTypeRepository.Load(mediaType);
    //Get a new empty file data
    var media = contentRepository.GetDefault<IContentMedia>(SiteDefinition.Current.GlobalAssetsRoot, contentType.ID);
    media.Name = "MyImages";
    var contentLink = contentRepository.Save(media, SaveAction.Publish, AccessLevel.NoAccess);
    // Add variation
    var variation = contentRepository.GetDefault<VariationContent>(rootCatalogLink, CultureInfo.GetCultureInfo("en-US"));
    variation.Name = "Variation name";
    contentRepository.Save(variation, SaveAction.Save, AccessLevel.NoAccess);
    var commerceMedia = new CommerceMedia() {
      AssetLink = contentLink
    };
    variation.CommerceMediaCollection.Add(commerceMedia);

    return assetUrlResolver.GetAssetUrl<IContentImage>(variation);
  }
}
```

## AssetUrlConventions

The `AssetUrlConventions` class can specify a default asset for a content type. The generic `AddDefaultGroup(string groupName)` method adds the specified group name as the default group for the generic type, which has to implement `IAssetContainer`.

You can have only one default group name for each specific content type. An `InvalidOperationException` is thrown if several default groups are set for the same content type.

### GetDefaultGroup

`GetDefaultGroup` gets the default group for the content. This method checks for the exact type, if there is a default group on that level. If there is no registered default group specified on the exact type, the method checks the base class for any default group registered on that type. The method recursively checks for a registered type until it is found, or until the base type no longer implements `IAssetContainer`.
