@model DevExtreme.MVC.Demos.Models.FileManagement.AzureStorageAccount
@if(!Model.IsEmpty()) {
@(Html.DevExtreme().FileManager()
.ID("file-manager")
.FileSystemProvider(provider => provider.Custom()
.GetItems("getItems")
.CreateDirectory("createDirectory")
.RenameItem("renameItem")
.DeleteItem("deleteItem")
.CopyItem("copyItem")
.MoveItem("moveItem")
.UploadFileChunk("uploadFileChunk")
.DownloadItems("downloadItems")
)
.Permissions(permissions => {
permissions.Download(true);
// uncomment the code below to enable file/folder management
// permissions.Create(true);
// permissions.Copy(true);
// permissions.Move(true);
// permissions.Delete(true);
// permissions.Rename(true);
// permissions.Upload(true);
})
.Upload(upload => upload.MaxFileSize(1048576))
.AllowedFileExtensions(new string[0])
)
<text>
<div id="request-panel"></div>
<script src="~/Scripts/utils/azure-file-system.js"></script>
<script>
function getItems(parentDirectory) {
return azure.getItems(parentDirectory.path);
}
function createDirectory(parentDirectory, name) {
return azure.createDirectory(parentDirectory.path, name);
}
function renameItem(item, name) {
return item.isDirectory ? azure.renameDirectory(item.path, name) : azure.renameFile(item.path, name);
}
function deleteItem(item) {
return item.isDirectory ? azure.deleteDirectory(item.path) : azure.deleteFile(item.path);
}
function copyItem(item, destinationDirectory) {
var destinationPath = destinationDirectory.path ? destinationDirectory.path + "/" + item.name : item.name;
return item.isDirectory ? azure.copyDirectory(item.path, destinationPath) : azure.copyFile(item.path, destinationPath);
}
function moveItem(item, destinationDirectory) {
var destinationPath = destinationDirectory.path ? destinationDirectory.path + "/" + item.name : item.name;
return item.isDirectory ? azure.moveDirectory(item.path, destinationPath) : azure.moveFile(item.path, destinationPath);
}
function uploadFileChunk(fileData, uploadInfo, destinationDirectory) {
var deferred = null;
if(uploadInfo.chunkIndex === 0) {
var filePath = destinationDirectory.path ? destinationDirectory.path + "/" + fileData.name : fileData.name;
deferred = gateway.getUploadAccessUrl(filePath).done(function(accessUrl) {
uploadInfo.customData.accessUrl = accessUrl;
});
} else {
deferred = $.Deferred().resolve().promise();
}
deferred = deferred.then(function() {
return gateway.putBlock(uploadInfo.customData.accessUrl, uploadInfo.chunkIndex, uploadInfo.chunkBlob);
});
if(uploadInfo.chunkIndex === uploadInfo.chunkCount - 1) {
deferred = deferred.then(function() {
return gateway.putBlockList(uploadInfo.customData.accessUrl, uploadInfo.chunkCount);
});
}
return deferred.promise();
}
function downloadItems(items) {
azure.downloadFile(items[0].path);
}
function onRequestExecuted(e) {
$("<div>").addClass("request-info").append(
createParameterInfoDiv("Method:", e.method),
createParameterInfoDiv("Url path:", e.urlPath),
createParameterInfoDiv("Query string:", e.queryString),
$("<br>")
)
.prependTo("#request-panel");
}
function createParameterInfoDiv(name, value) {
return $("<div>").addClass("parameter-info").append(
$("<div>").addClass("parameter-name").text(name),
$("<div>").addClass("parameter-value dx-theme-accent-as-text-color").text(value).attr("title", value)
);
}
var endpointUrl = '@Url.HttpRouteUrl("FileManagerAzureAccessApi", null)';
var gateway = new AzureGateway(endpointUrl, onRequestExecuted);
var azure = new AzureFileSystem(gateway);
</script>
</text>
}
else {
<text>
To run the demo locally, specify your Azure storage account name, access key and container name in the web.config file.
Refer to the <a href="https://js.devexpress.com/Demos/WidgetsGallery/Demo/FileManager/AzureClientBinding/Mvc/Light/" target="_blank">
https://js.devexpress.com/Demos/WidgetsGallery/Demo/FileManager/AzureClientBinding/Mvc/Light/
</a> to see the demo online.
</text>
}
using DevExtreme.MVC.Demos.Models.FileManagement;
using System.Web.Mvc;
namespace DevExtreme.MVC.Demos.Controllers {
public class FileManagerController : Controller {
public ActionResult AzureClientBinding() {
return View(AzureStorageAccount.FileManager.Value);
}
}
}
using DevExtreme.MVC.Demos.Models.FileManagement;
using System;
using System.Net.Http;
using System.Web.Http;
using Azure.Storage;
using Azure.Storage.Sas;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;
namespace DevExtreme.MVC.Demos.Controllers.ApiControllers {
public class FileManagerAzureAccessApiController : ApiController {
const string EmptyDirDummyBlobName = "aspxAzureEmptyFolderBlob";
const string ServiceUri = "https://{0}.blob.core.windows.net";
const long MaxBlobSize = 1048576;
public FileManagerAzureAccessApiController() {
AllowDownload = true;
//uncomment the code below to enable file/folder management
//AllowCreate = true;
//AllowRemove = true;
//AllowRenameOrMoveOrCopy = true;
//AllowUpload = true;
}
bool AllowCreate { get; }
bool AllowRemove { get; }
bool AllowRenameOrMoveOrCopy { get; }
bool AllowUpload { get; }
bool AllowDownload { get; }
BlobServiceClient _client;
BlobServiceClient Client {
get {
if(_client == null) {
AzureStorageAccount accountModel = AzureStorageAccount.FileManager.Value;
StorageSharedKeyCredential credential = new StorageSharedKeyCredential(accountModel.AccountName, accountModel.AccessKey);
_client = new BlobServiceClient(new Uri(string.Format(ServiceUri, accountModel.AccountName)), credential);
}
return _client;
}
}
BlobContainerClient _container;
BlobContainerClient Container {
get {
if(_container == null) {
AzureStorageAccount accountModel = AzureStorageAccount.FileManager.Value;
_container = Client.GetBlobContainerClient(accountModel.ContainerName);
}
return _container;
}
}
[HttpGet]
[Route("api/file-manager-azure-access", Name = "FileManagerAzureAccessApi")]
public HttpResponseMessage Process(string command, string blobName = null, string blobName2 = null) {
object result;
try {
result = ProcessCommand(command, blobName, blobName2);
} catch {
result = CreateErrorResult();
}
return Request.CreateResponse(result);
}
object ProcessCommand(string command, string blobName, string blobName2) {
switch(command) {
case "BlobList":
return GetBlobList();
case "CreateDirectory":
if(!AllowCreate)
return CreateErrorResult();
return CreateDirectory(blobName);
case "DeleteBlob":
if(!AllowRemove)
return CreateErrorResult();
return DeleteBlob(blobName);
case "CopyBlob":
if(!AllowRenameOrMoveOrCopy)
return CreateErrorResult();
return CopyBlob(blobName, blobName2);
case "UploadBlob":
if(!AllowUpload)
return CreateErrorResult();
return UploadBlob(blobName);
case "GetBlob":
if(!AllowDownload)
return CreateErrorResult();
return GetBlob(blobName);
}
return null;
}
object GetBlobList() {
if(Container.CanGenerateSasUri) {
var sasUri = Container.GenerateSasUri(BlobContainerSasPermissions.List, DateTimeOffset.UtcNow.AddHours(1));
return CreateSuccessResult(sasUri);
} else {
return CreateErrorResult("BlobContainerClient cannot generate SasUri");
}
}
object CreateDirectory(string directoryName) {
string blobName = $"{directoryName}/{EmptyDirDummyBlobName}";
var blob = Container.GetBlobClient(blobName);
if(blob.Exists()) {
return CreateErrorResult();
}
var sasUri = TryGetBlobUri(blob, BlobSasPermissions.Write);
if(sasUri != null) {
return CreateSuccessResult(sasUri);
} else {
return CreateErrorResult("BlobClient cannot generate SasUri");
}
}
object DeleteBlob(string blobName) {
var sasUri = TryGetBlobUri(blobName, BlobSasPermissions.Delete);
if(sasUri != null) {
return CreateSuccessResult(sasUri);
} else {
return CreateErrorResult("BlobClient cannot generate SasUri");
}
}
object CopyBlob(string sourceBlobName, string destinationBlobName) {
var sourceSasUri = TryGetBlobUri(sourceBlobName, BlobSasPermissions.Read);
var destinationSasUri = TryGetBlobUri(destinationBlobName, BlobSasPermissions.Create);
if(sourceSasUri != null && destinationSasUri != null) {
return CreateSuccessResult(sourceSasUri, destinationSasUri);
} else {
return CreateErrorResult("BlobClient cannot generate SasUri");
}
}
object UploadBlob(string blobName) {
if(blobName.EndsWith("/"))
return CreateErrorResult("Invalid blob name.");
var blob = Container.GetBlockBlobClient(blobName);
if(blob.Exists() && blob.GetProperties().Value.ContentLength > MaxBlobSize) {
return CreateErrorResult();
}
var sasUri = TryGetBlobUri(blobName, BlobSasPermissions.Write);
return CreateSuccessResult(sasUri);
}
object GetBlob(string blobName) {
var headers = new BlobHttpHeaders {
ContentType = "application/octet-stream"
};
var blob = Container.GetBlobClient(blobName);
blob.SetHttpHeaders(headers);
var sasUri = TryGetBlobUri(blob, BlobSasPermissions.Read);
return CreateSuccessResult(sasUri);
}
Uri TryGetBlobUri(string blobName, BlobSasPermissions permissions) {
if(!string.IsNullOrEmpty(blobName)) {
return TryGetBlobUri(Container.GetBlobClient(blobName), permissions);
} else {
return null;
}
}
Uri TryGetBlobUri(BlobClient blob, BlobSasPermissions permissions) {
if(blob.CanGenerateSasUri) {
return blob.GenerateSasUri(permissions, DateTimeOffset.UtcNow.AddHours(1));
} else {
return null;
}
}
object CreateSuccessResult(Uri uri, Uri uri2 = null) {
return new {
success = true,
accessUrl = uri.AbsoluteUri,
accessUrl2 = uri2 != null ? uri2.AbsoluteUri : null
};
}
object CreateErrorResult(string error = null) {
if(string.IsNullOrEmpty(error))
error = "Unspecified error.";
return new {
success = false,
error = error
};
}
}
}
#request-panel {
min-width: 505px;
height: 400px;
overflow-x: hidden;
overflow-y: auto;
padding: 18px;
margin-top: 40px;
background-color: rgba(191, 191, 191, 0.15);
}
#request-panel .parameter-info {
display: flex;
}
.request-info .parameter-name {
flex: 0 0 100px;
}
.request-info .parameter-name,
.request-info .parameter-value {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}