HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

BLOB storage and providers

Explains the concept and usage of BLOBs (Binary Large Objects) in Optimizely Content Management System (CMS) version 11.3 to 11.20.

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 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 a local disc or a file share defined during installation.
  • Customized BLOB provider for your specific hosting environment, such as BLOB providers for Microsoft Azure and Amazon Web Services, available from the Optimizely NuGet feed.

BLOB architecture

A provider is responsible for storing a data stream and associating it with a unique identifier. You group BLOBs into containers, a logical name for a set of BLOBs you can delete with a single API call. It exposes the unique identifier 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 the caller is assumed to keep 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 Work with media.

Configuring a custom BLOB provider

Add a BLOB element to the episerver.framework section in web.config to define a custom provider:

<episerver.framework>
      <blob defaultProvider="myProvider">
        <providers>
          <add name="myProvider" type="MyAssembly.Provider, MyAssembly" />
        </providers>
      </blob>
    </episerver.framework>

Another option is to add the BLOB provider programmatically during the configuration phase of the site initialization. Create an initialization module that implements the IConfigurableModule interface and handle the registration in the ConfigureContainer method through one of the extension methods available on the context.Services property or by configuring the BlobOptions class directly.

[InitializableModule]
[ModuleDependency(typeof (FrameworkInitialization))]
public class CustomBlobProviderInitialization: IConfigurableModule {
  public void ConfigureContainer(ServiceConfigurationContext context) {
    // This provider will be added as the default
    context.Services.AddFileBlobProvider("myFileBlobProvider", @ "c:\path\to\file\blobs");
    context.Services.AddBlobProvider<MyCustomBlobProvider>("myCustomBlobProvider",
      default: false);
    context.Services.Configure<BlobOptions>(o => {
      o.AddProvider<MyCustomBlobProvider>("anotherCustomBlobProvider");
      o.DefaultProvider = "anotherCustomBlobProvider";
    });
  }

  public void Initialize(InitializationEngine context) {}
  public void Uninitialize(InitializationEngine context) {}
}