API REST общего доступа к файлам Azure для Xamarin

В Xamarin клиентское приложение, я хочу получить доступ к файлам Azure, используя SAS знак с Portable Class Library, Кажется, я не могу сделать это, используя последний пакет https://www.nuget.org/packages/WindowsAzure.Storage/, так как он может работать только с Blob, Table,... и требует много зависимостей.

Есть ли способ сделать это?

1 ответ

Решение

В итоге я использовал REST API хранилища файлов Azure. Обычно мы запрашиваем токен SAS, сгенерированный из общего ресурса Azure, а затем используем этот токен SAS в URL для отправки http-запроса в хранилище файлов Azure:

https://%5Byourshare%5D.file.core.windows.net/%5Byourdirectory%5D/%5Byourfile%5D?%5Byour_sas_token%5D

Я создал класс, чтобы помочь клиенту выполнять некоторые основные операции, как показано ниже (это переносимый класс, поэтому его можно использовать в любом месте на стороне клиента):

public class AzureFileREST
    {
        private AzureSASToken _azureShareToken;

        public AzureFileREST(AzureSASToken azureShareToken)
        {
            _azureShareToken = azureShareToken;
        }

        public async Task CreateIfNotExist(string directoryName)
        {
            var existed = await CheckDirectoryExists(directoryName);
            if (!existed)
            {
                await CreateDirectory(directoryName);
            }
        }

        public async Task<bool> CheckDirectoryExists(string directoryName)
        {
            using (var client = new HttpClient())
            {
                //Get directory (https://msdn.microsoft.com/en-us/library/azure/dn194272.aspx)
                var azureCreateDirUrl = _azureShareToken.Url + directoryName + _azureShareToken.SASToken + "&restype=directory";
                var response = await client.GetAsync(azureCreateDirUrl).ConfigureAwait(false);
                return (response.StatusCode != System.Net.HttpStatusCode.NotFound);
            }
        }

        public async Task CreateDirectory(string directoryName)
        {   
            using (var client = new HttpClient())
            {
                //Create directory (https://msdn.microsoft.com/en-us/library/azure/dn166993.aspx)
                var azureCreateDirUrl = _azureShareToken.Url + directoryName + _azureShareToken.SASToken + "&restype=directory";
                var response = await client.PutAsync(azureCreateDirUrl, null).ConfigureAwait(false);
                response.EnsureSuccessStatusCode();
            }
        }

        public async Task UploadFile(string fileName, byte[] fileBytes)
        {
            using (var client = new HttpClient())
            {
                //Create empty file first (https://msdn.microsoft.com/en-us/library/azure/dn194271.aspx)
                var azureCreateFileUrl = _azureShareToken.Url + fileName + _azureShareToken.SASToken;
                client.DefaultRequestHeaders.Add("x-ms-type", "file");
                client.DefaultRequestHeaders.Add("x-ms-content-length", fileBytes.Length.ToString());
                var response = await client.PutAsync(azureCreateFileUrl, null).ConfigureAwait(false);
                response.EnsureSuccessStatusCode();

                //Then upload file (https://msdn.microsoft.com/en-us/library/azure/dn194276.aspx)                
                var azureUploadFileUrl = azureCreateFileUrl + "&comp=range";
                client.DefaultRequestHeaders.Clear();
                client.DefaultRequestHeaders.Add("x-ms-write", "update");
                client.DefaultRequestHeaders.Add("x-ms-range", String.Format("bytes=0-{0}", (fileBytes.Length - 1).ToString()));

                var byteArrayContent = new ByteArrayContent(fileBytes);
                response = await client.PutAsync(azureUploadFileUrl, byteArrayContent).ConfigureAwait(false);
                response.EnsureSuccessStatusCode();
            }
        }
    }

На стороне сервера используйте следующую функцию для генерации SAS токен от Share:

public AzureSASToken GetSASFromShare(string shareName)
        {
            var share = _fileclient.GetShareReference(shareName);
            share.CreateIfNotExists();
            string policyName = "UPARSharePolicy";

            // Create a new shared access policy and define its constraints.
            var sharedPolicy = new SharedAccessFilePolicy()
            {
                SharedAccessExpiryTime = DateTime.UtcNow.AddDays(15),
                Permissions = SharedAccessFilePermissions.Read | SharedAccessFilePermissions.Write
            };

            // Get existing permissions for the share.
            var permissions = share.GetPermissions();

            // Add the shared access policy to the share's policies. 
            // Note that each policy must have a unique name.
            // Maximum 5 policies for each share!
            if (!permissions.SharedAccessPolicies.Keys.Contains(policyName))
            {
                if (permissions.SharedAccessPolicies.Count > 4)
                {
                    var lastAddedPolicyName = permissions.SharedAccessPolicies.Keys.Last();
                    permissions.SharedAccessPolicies.Remove(lastAddedPolicyName);
                }
                permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
                share.SetPermissions(permissions);
            }            

            var sasToken = share.GetSharedAccessSignature(sharedPolicy);
            //fileSasUri = new Uri(share.StorageUri.PrimaryUri.ToString() + sasToken);
            return new AzureSASToken ()
            {
               Name = shareName,
               Url = share.StorageUri.PrimaryUri.ToString() + "/",
               SASToken = sasToken        
            };
        }

Наконец, используя класс, как это:

var azureFileRest = new AzureFileREST(sasToken);
await azureFileRest.CreateIfNotExist(directoryName);
await azureFileRest.UploadFile(directoryName + "/" + fileName, bytes);
Другие вопросы по тегам