@model DevExtreme.NETCore.Demos.Models.FileManagement.AzureStorageAccount
@if(!Model.IsEmpty()) {
@(Html.DevExtreme().FileManager()
.ID("file-manager")
.FileProvider(fileProvider => fileProvider.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.Remove(true);
// permissions.Rename(true);
// permissions.Upload(true);
})
.Upload(upload => upload.MaxFileSize(1048576))
.AllowedFileExtensions(new string[0])
)
<text>
<div id="request-panel"></div>
<script src="~/utils/azure-file-system.js"></script>
<script>
function getItems(pathInfo) {
var path = getPath(pathInfo);
return azure.getItems(path);
}
function createDirectory(parentDirectory, name) {
var path = getPath(parentDirectory.getFullPathInfo());
return azure.createDirectory(path, name);
}
function renameItem(item, name) {
var path = getPath(item.getFullPathInfo());
return item.isDirectory ? azure.renameDirectory(path, name) : azure.renameFile(path, name);
}
function deleteItem(item) {
var path = getPath(item.getFullPathInfo());
return item.isDirectory ? azure.deleteDirectory(path) : azure.deleteFile(path);
}
function copyItem(item, destinationDirectory) {
var sourcePath = getPath(item.getFullPathInfo());
var destinationDirPath = getPath(destinationDirectory.getFullPathInfo());
var destinationPath = destinationDirPath ? destinationDirPath + "/" + item.name : item.name;
return item.isDirectory ? azure.copyDirectory(sourcePath, destinationPath) : azure.copyFile(sourcePath, destinationPath);
}
function moveItem(item, destinationDirectory) {
var sourcePath = getPath(item.getFullPathInfo());
var destinationDirPath = getPath(destinationDirectory.getFullPathInfo());
var destinationPath = destinationDirPath ? destinationDirPath + "/" + item.name : item.name;
return item.isDirectory ? azure.moveDirectory(sourcePath, destinationPath) : azure.moveFile(sourcePath, destinationPath);
}
function uploadFileChunk(fileData, uploadInfo, destinationDirectory) {
var deferred = null;
if(uploadInfo.chunkIndex === 0) {
var path = getPath(destinationDirectory.getFullPathInfo());
var filePath = path ? 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) {
var item = items[0];
var path = getPath(item.getFullPathInfo());
azure.downloadFile(path);
}
function getPath(pathInfo) {
return pathInfo.map(function(part) { return part.name; }).join("/");
}
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.RouteUrl("FileManagerAzureAccessApi")';
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 appsettings.json file.
Refer to the <a href="https://demos.devexpress.com/ASPNetCore/Demo/FileManager/AzureClientBinding/">
https://demos.devexpress.com/ASPNetCore/Demo/FileManager/AzureClientBinding/
</a> to see the demo online.
</text>
}
using DevExtreme.NETCore.Demos.Models.FileManagement;
using Microsoft.AspNetCore.Mvc;
namespace DevExtreme.NETCore.Demos.Controllers {
public class FileManagerController : Controller {
public IActionResult AzureClientBinding() {
return View(AzureStorageAccount.FileManager);
}
}
}
using DevExtreme.NETCore.Demos.Models.FileManagement;
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Auth;
using Microsoft.Azure.Storage.Blob;
using Microsoft.AspNetCore.Mvc;
using System;
namespace DevExtreme.NETCore.Demos.Controllers {
public class FileManagerAzureAccessApiController : Controller {
const string EmptyDirDummyBlobName = "aspxAzureEmptyFolderBlob";
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; }
CloudBlobClient _client;
CloudBlobClient Client {
get {
if(this._client == null) {
AzureStorageAccount accountModel = AzureStorageAccount.FileManager;
var credentials = new StorageCredentials(accountModel.AccountName, accountModel.AccessKey);
var account = new CloudStorageAccount(credentials, true);
this._client = account.CreateCloudBlobClient();
}
return this._client;
}
}
CloudBlobContainer _container;
CloudBlobContainer Container {
get {
if(this._container == null) {
AzureStorageAccount accountModel = AzureStorageAccount.FileManager;
this._container = Client.GetContainerReference(accountModel.ContainerName);
}
return this._container;
}
}
[Route("api/file-manager-azure-access", Name = "FileManagerAzureAccessApi")]
public object Process(string command, string blobName = null, string blobName2 = null) {
try {
return ProcessCommand(command, blobName, blobName2);
} catch {
return CreateErrorResult();
}
}
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() {
var policy = CreateSharedAccessBlobPolicy(SharedAccessBlobPermissions.List);
string url = Container.Uri + Container.GetSharedAccessSignature(policy, null, SharedAccessProtocol.HttpsOnly, null);
return CreateSuccessResult(url);
}
object CreateDirectory(string directoryName) {
string blobName = $"{directoryName}/{EmptyDirDummyBlobName}";
CloudBlockBlob blob = Container.GetBlockBlobReference(blobName);
if(blob.Exists()) {
if(blob.Properties.Length > 0) {
blob.Delete();
}
return CreateErrorResult();
}
string url = GetSharedAccessSignature(blob, SharedAccessBlobPermissions.Write);
return CreateSuccessResult(url);
}
object DeleteBlob(string blobName) {
string url = GetSharedAccessSignature(blobName, SharedAccessBlobPermissions.Delete);
return CreateSuccessResult(url);
}
object CopyBlob(string sourceBlobName, string destinationBlobName) {
string sourceUrl = GetSharedAccessSignature(sourceBlobName, SharedAccessBlobPermissions.Read);
string destinationUrl = GetSharedAccessSignature(destinationBlobName, SharedAccessBlobPermissions.Create);
return CreateSuccessResult(sourceUrl, destinationUrl);
}
object UploadBlob(string blobName) {
if(blobName.EndsWith("/"))
return CreateErrorResult("Invalid blob name.");
CloudBlockBlob blob = Container.GetBlockBlobReference(blobName);
if(blob.Exists() && blob.Properties.Length > MaxBlobSize) {
blob.Delete();
return CreateErrorResult();
}
string url = GetSharedAccessSignature(blob, SharedAccessBlobPermissions.Write);
return CreateSuccessResult(url);
}
object GetBlob(string blobName) {
var headers = new SharedAccessBlobHeaders {
ContentType = "application/octet-stream"
};
string url = GetSharedAccessSignature(blobName, SharedAccessBlobPermissions.Read, headers);
return CreateSuccessResult(url);
}
string GetSharedAccessSignature(string blobName, SharedAccessBlobPermissions permissions, SharedAccessBlobHeaders headers = null) {
CloudBlockBlob blob = Container.GetBlockBlobReference(blobName);
return GetSharedAccessSignature(blob, permissions, headers);
}
string GetSharedAccessSignature(CloudBlockBlob blob, SharedAccessBlobPermissions permissions, SharedAccessBlobHeaders headers = null) {
SharedAccessBlobPolicy policy = CreateSharedAccessBlobPolicy(permissions);
return blob.Uri + blob.GetSharedAccessSignature(policy, headers, null, SharedAccessProtocol.HttpsOnly, null);
}
SharedAccessBlobPolicy CreateSharedAccessBlobPolicy(SharedAccessBlobPermissions permissions) {
return new SharedAccessBlobPolicy {
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(1),
Permissions = permissions
};
}
object CreateSuccessResult(string url, string url2 = null) {
return new {
success = true,
accessUrl = url,
accessUrl2 = url2
};
}
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;
}