Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
EPiServer Commerce provides several options for storing assets. Out-of-the-box, EPiServer Commerce comes with providers for file storage, MSSQL storage and Amazon S3. You can also create your own asset management provider. This document describes the usage of some of the storage options available.
Classes referred to here are available in the following namespaces:
In the Web.Config file of your EPiServer Commerce site under the element section, the AssetManagement element will point to the file ecf.asset.config.CommerceFramework.
Example: asset configuration section
<CommerceFramework>
<!-- Asset Configuration -->
<AssetManagement configSource="Configs\ecf.asset.config"></AssetManagement>
</CommerceFramework>
In ecf.asset.config you can declaratively specify different values for FolderProviders, DownloadFilters, and ElementTypes. These are made accessible through the static Instance property of the AssetConfiguration class.
What these asset types does:
Example: specifying folders, downloads and element types
<!-- Accessed through AssetConfiguration.Instance.FolderProviders -->
<FolderProviders>
<add path="\Root\Cloud\*">
<add storageProvider="S3StorageProvider" downloadProfile="s3"/>
</add>
<add path="\Root\Database\*">
<add storageProvider="SqlBlobStorageProvider" downloadProfile="open"/>
</add>
<add path="\*">
<add storageProvider="PublicDiskBlobStorageProvider" downloadProfile="iis"/>
</add>
</FolderProviders>
<!-- Accessed through AssetConfiguration.Instance.DownloadFilters -->
<DownloadFilters>
<add name="thumbnail" type="Mediachase.Commerce.Assets.DownloadFilterThumbnail, Mediachase.Commerce"/>
</DownloadFilters>
<!-- Accessed through AssetConfiguration.Instance.ElementTypes -->
<ElementTypes>
<add mimeType="image/jpeg" type="Mediachase.Commerce.Assets.ImageFolderElementExtension, Mediachase.Commerce"/>
</ElementTypes>
The following blob (binary large object) storage provider types are available out-of-the-box:
SqlBlobStorageProvider and PublicDiskBlobStorageProvider are types defined in the Mediachase.BusinessFoundation assembly. They extend the abstract class BlobStorageProvider which defines a set of properties and methods for blob storing of data.
The following storage provider type is available out-of-the-box for Amazon S3 storage:
S3StorageProvider is a type defined in the Mediachase.Library.AmazonProviders assembly. It extends the abstract class BlobStorageProvider which defines a set of properties and methods for blob (binary large object) storing of data. Refer also to Amazon Simple Storage Service (Amazon S3) for more information
The collection of declaratively set FolderProviders are used by the FolderElementEntity class to store blob data. Operations on the blob data are abstracted away through the FolderElementEntity class's methods.
Example: using FolderElementEntity for blob storage
/// <summary>
/// Creates a new folder element.
/// </summary>
/// <param name="parentId">The parent id.</param>
/// <param name="fileName">The Name of the file.</param>
/// <param name="content">The content stream.</param>
/// <param name="progressId">The progress id.</param>
/// <returns></returns>
public static FolderElementEntity Create(int parentId, string fileName, Stream content, Guid progressId)
{
FolderElementEntity result = new FolderElementEntity();
result.ParentId = parentId;
BlobInfo blobInfo = new BlobInfo(Guid.NewGuid());
// Try recognizing the provider from configuration settings.
BlobStorageProvider provider = BlobStorage.Provider;
String providerName;
String contentType = Mediachase.BusinessFoundation.Blob.ContentTypeResolver.ContentType.ResolveByPath(fileName);
long fileSize = content.Length;
if (TryRecognizeStorageProvider(result, fileName, contentType, fileSize, out providerName))
provider = BlobStorage.Providers[providerName];
blobInfo.FileName = fileName;
blobInfo.Provider = provider.Name;
blobInfo.Created = DateTime.UtcNow;
blobInfo.ContentSize = fileSize;
blobInfo.ContentType = contentType;
// The content type assigned by provider.
// Save blob info to storage.
using (Stream stream = provider.CreateStream(blobInfo))
{
WriteToStream(stream, content, 0, fileSize, progressId);
}
provider.CommitStream(blobInfo);
result.BlobStorageProvider = provider.Name;
result.BlobUid = blobInfo.Uid;
result.Created = DateTime.UtcNow;
result.Name = blobInfo.FileName;
if (result.Properties.Contains("ContentSize"))
result.Properties["ContentSize"].Value = (Int32)blobInfo.ContentSize;
if (result.Properties.Contains("ContentType"))
result.Properties["ContentType"].Value = blobInfo.ContentType;
// try
IFolderElementExtension folderElement = GetCfgFolderElementExtension(blobInfo);
if (folderElement != null)
folderElement.Process(result);
result.PrimaryKeyId = BusinessManager.Create(result);
return result;
}
// ...
/// <summary>
/// Tries the recognize provider.
/// </summary>
/// <param name="element">The element.</param>
/// <param name="fileName">Name of the file.</param>
/// <param name="contentType">Type of the content.</param>
/// <param name="fileSize">Size of the file.</param>
/// <param name="providerName">Name of the provider.</param>
/// <param name="profileName">Name of the profile.</param>
/// <returns></returns>
public static bool TryRecognizeStorageProvider(
FolderElementEntity element
, string fileName
, String contentType
, long fileSize
, out String providerName
, out string profileName
)
{
providerName = String.Empty;
profileName = String.Empty;
FileLibraryLocationCollection locations = AssetConfiguration.Instance.FolderProviders;
if (locations != null)
{
Dictionary<String, LocationRuleElement> matchList = new Dictionary<string, LocationRuleElement>();
string hierarhy = element.GetElementPath("\\");
foreach (FileLibraryLocationElement location in locations)
{
bool wildcard = location.Path.EndsWith(ConstWildcardCharacter);
string locationPath = wildcard == true ?
location.Path.Substring(0, location.Path.IndexOf(ConstWildcardCharacter))
: location.Path;
if (hierarhy.Equals(locationPath, StringComparison.InvariantCultureIgnoreCase)
|| ((wildcard == true) && (hierarhy.StartsWith(locationPath, StringComparison.InvariantCultureIgnoreCase))))
{
LocationRuleCollections rules = location.LocationRules;
foreach (LocationRuleElement rule in rules)
{
bool found = true;
if (!String.IsNullOrEmpty(rule.Extension))
{
found = fileName.EndsWith(rule.Extension,
StringComparison.InvariantCultureIgnoreCase) ? found : false;
}
if (!String.IsNullOrEmpty(rule.MimeType))
{
found = contentType.Equals(rule.MimeType,
StringComparison.InvariantCultureIgnoreCase) ? found : false;
}
if (!String.IsNullOrEmpty(rule.MaxSize))
{
String regExpPat = @"(?<size>[0-9]+)\s*(?<unit>Kb|Mb|Gb)?";
Regex regExp = new Regex(regExpPat, RegexOptions.IgnoreCase);
Match sizeMatch = regExp.Match(rule.MaxSize);
if (sizeMatch.Success)
{
long maxSize = Convert.ToInt64(sizeMatch.Groups["size"].Value);
string unit = sizeMatch.Groups["unit"].Value;
if (!String.IsNullOrEmpty(unit))
{
if (unit.Equals("Kb", StringComparison.InvariantCultureIgnoreCase))
maxSize *= 1024;
else if (unit.Equals("Mb", StringComparison.InvariantCultureIgnoreCase))
maxSize *= 1048576;
else if (unit.Equals("Gb", StringComparison.InvariantCultureIgnoreCase))
maxSize *= 1073741824;
}
found = fileSize >= maxSize ? found : false;
}
}
if ((found == true) || (String.IsNullOrEmpty(rule.MaxSize)
&& String.IsNullOrEmpty(rule.MimeType)
&& String.IsNullOrEmpty(rule.MaxSize)))
{
matchList.Add(location.Path, rule);
break;
}
}
}
}
if (matchList.Count != 0)
{
// Get the location element with max depth.
int maxDepth = -1;
String maxKey = String.Empty;
foreach (String key in matchList.Keys)
{
int depth = key.Split(new Char[] { '\\' }).Length;
if (depth > maxDepth)
{
maxDepth = depth;
maxKey = key;
}
}
providerName = matchList[maxKey].StorageProvider;
profileName = matchList[maxKey].DownloadProfile;
return true;
}
}
return false;
}
Last updated: Oct 21, 2014