This is a an Azure Blob Storage context used by Sky CMS and can be used by any .Net Core. project.
It is a simple wrapper around the Azure Blob Storage SDK that provides a more convenient way to interact with the Azure Blob Storage.
How to install:
From the Nuget Package Manager Console:
Install-Package Cosmos.BlobServiceFrom the .Net CLI:
dotnet add package Cosmos.BlobServiceHow to create the context:
In the program secrets, add the connection string to the Azure Blob Storage account like this:
{
"ConnectionStrings": {
"AzureBlobStorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=[YOUR-ACCOUNT-NAME];AccountKey=[YOUR-ACCOUNT-KEY]"
}
}If you are using a managed identity--and not an account key--define the connection like this:
{
"ConnectionStrings": {
"AzureBlobStorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=[YOUR-ACCOUNT-NAME];AccountKey=AccessToken
}
}Notice the account key is set to "AccessToken". This is how the Azure Blob Storage context knows to use the managed identity.
NOTE: For a full example of this package in use, please see the Sky CMS project file manager controller.
Meanwhile, here is an example of how to use the context in a .Net Core project.
In the Startup.cs or Project.cs file, add this using statement:
using Cosmos.BlobService;And then add this line to the ConfigureServices method:
// Add the BLOB and File Storage contexts for Sky CMS
builder.Services.AddCosmosStorageContext(builder.Configuration);How to use the context:
In the class where you want to use the Azure Blob Storage context, inject the context like this:
namespace Cosmos.Publisher.Controllers
{
/// <summary>
/// Secure file access controller and proxy.
/// </summary>
[AllowAnonymous]
public class PubController : ControllerBase
{
private readonly StorageContext storageContext;
/// <summary>
/// Initializes a new instance of the <see cref="PubController"/> class.
/// </summary>
/// <param name="options">Cosmos options.</param>
/// <param name="dbContext">Database context.</param>
/// <param name="storageContext">Storage context.</param>
public PubController(StorageContext storageContext)
{
this.storageContext = storageContext;
}
}
}Here is example code for reading a file from Azure Blob Storage:
/// <summary>
/// Gets a file and validates user authentication.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public virtual async Task<IActionResult> Index(string path)
{
var client = storageContext.GetAppendBlobClient(path);
var properties = await client.GetPropertiesAsync();
return File(fileStream: await client.OpenReadAsync(), contentType: properties.Value.ContentType, lastModified: properties.Value.LastModified, entityTag: new EntityTagHeaderValue(properties.Value.ETag.ToString()));
}Then you can use the context to upload an image file Azure Blob Storage like this:
/// <summary>
/// Simple image upload.
/// </summary>
public async Task<IActionResult> SimpleUpload(string directory, string entityType = "articles", string editorType = "ckeditor")
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Gets the file being uploaded.
var file = Request.Form.Files.FirstOrDefault();
if (file.Length > (1048576 * 25))
{
return Json(ReturnSimpleErrorMessage("The image upload failed because the image was too big (max 25MB)."));
}
var extension = Path.GetExtension(file.FileName).ToLower();
var fileName = $"{Guid.NewGuid().ToString().ToLower()}{extension}";
var image = await Image.LoadAsync(file.OpenReadStream());
string relativePath = UrlEncode(directory + fileName);
var contentType = MimeTypeMap.GetMimeType(Path.GetExtension(fileName));
var metaData = new FileUploadMetaData()
{
ChunkIndex = 0,
ContentType = contentType,
FileName = fileName,
RelativePath = relativePath,
TotalChunks = 1,
TotalFileSize = file.Length,
UploadUid = Guid.NewGuid().ToString(),
ImageHeight = image.Height.ToString(),
ImageWidth = image.Width.ToString(),
};
// Read the file into a memory stream.
using var memoryStream = new MemoryStream();
await file.CopyToAsync(memoryStream);
// Append the blob to the storage.
storageContext.AppendBlob(memoryStream, metaData);
return Json(JsonConvert.DeserializeObject<dynamic>("{\"url\": \"" + "/" + relativePath + "\"}"));
}