Loading...
Area: Optimizely CMS
Applies to versions: 12 and higher
Other versions:
ARCHIVED This content is retired and no longer maintained. See the version selector for other versions of this topic.

BLOB storage and providers

Recommended reading 
Note: This documentation is for the preview version of the upcoming release of CMS 12/Commerce 14/Search & Navigation 14. Features included here might not be complete, and might be changed before becoming available in the public release. This documentation is provided for evaluation purposes only.

This topic explains the concept and usage of BLOBs (Binary Large Objects) in Optimizely. BLOB providers are a framework designed to store large amounts of binary data in an optimized and cost-effective solution, such as cloud storage instead of in a database.

BLOB providers

The Optimizely platform supports BLOB storage of assets using a provider-based setup, and has a built-in file BLOB provider. You have the following options:

  • Built-in BLOB provider for media files such as images, videos, and documents, stored on local disc or a file share that is defined during installation.
  • Customized BLOB provider for your specific hosting environment, such as BLOB providers for Microsoft Azure and Amazon Web Services, which are available from the Optimizely NuGet feed.

BLOB architecture

A provider is responsible for storing a stream of data and associate it with a unique identifier. BLOBs are grouped into containers which is a logical name for a set of BLOBs, which you can delete with a single API call. The unique identifier is exposed as a URI in the format epi.fx.blob://[provider]/[container]/[blob] to store a reference to a BLOB in a database.

Most methods in the API return a reference even though the actual BLOB does not exist, because it would be too costly to access a cloud service every time; for example, a call to GetBlob is made, and it is assumed that the caller keeps track of BLOB identifiers.

The example below shows how to use a BLOB provider.

public void ReadWriteBlobs()
{
    var blobFactory = ServiceLocator.Current.GetInstance<IBlobFactory>();

    //Define a container
    var container = Blob.GetContainerIdentifier(Guid.NewGuid());

    //Uploading a file to a blob
    var blob1 = blobFactory.CreateBlob(container, ".png");
    using (var fs = new FileStream("c:\\myfile.png", FileMode.Open))
    {
        blob1.Write(fs);
    }

    //Writing custom data to a blob
    var blob2 = blobFactory.CreateBlob(container, ".txt");
    using (var s = blob2.OpenWrite())
    {
        var w = new StreamWriter(s);
        w.WriteLine("Hello World!");
        w.Flush();
    }

    //Reading from a blob based on ID
    var blobID = blob2.ID;
    var blob3 = blobFactory.GetBlob(blobID);
    using (var s = blob3.OpenRead())
    {
        var helloWorld = new StreamReader(s).ReadToEnd();
    }

    //Delete single blob
    blobFactory.Delete(blobID);

    //Delete container
    blobFactory.Delete(container);
}

Note: When you delete a container under the website root, if you use the FileBlob provider, it leaves empty folders under the website root. If you use the Azure or the Amazon provider, it deletes the containers. For information about handling media in the assets pane, see Working with media.

Configuring a custom BLOB provider

Add a BlobProvidersOptions in appsettings.json under episerver/cms element to define a custom provider:

{
  "EPiServer" : {
    "Cms" : {
      "BlobProvidersOptions" : {
        DefaultProvider": "Custom",
        "Providers" : {
          "Custom"  : "CustomProvider, Customassembly"
          "Another" : "Another_CustomProvider, Customassembly"
        }
      }
    }
  }
}

Another option is to add the BLOB provider programmatically during the configuration phase of the site. This can be done by using IServiceCollection or by configuring the BlobOptions class directly.

public void ConfigureServices(IServiceCollection services)
{
  // This provider will be added as the default
    services.AddFileBlobProvider("myFileBlobProvider", @"c:\path\to\file\blobs");
    services.AddBlobProvider<MyCustomBlobProvider>("myCustomBlobProvider", defaultProvider: false);
    services.Configure<MyCustomBlobProvider>(o => 
      {
        o.AddProvider<MyCustomBlobProvider>("anotherCustomBlobProvider");
        o.DefaultProvider = "anotherCustomBlobProvider";
      });
}

Related topics

Do you find this information helpful? Please log in to provide feedback.

Last updated: Jul 02, 2021

Recommended reading