Azure File Share REST API for Xamarin

夙愿已清 提交于 2019-12-25 04:14:04

问题


In Xamarin client app, I want to access Azure Files using SAS token with Portable Class Library. It seems I can not do it using latest WindowAzure.Storage nuget package as it may only works with Blob, Table,... and it requires lots of dependencies.

Is there anyway to accomplish this?


回答1:


I ended up with using Azure File Storage REST API. Basically we request SAS token generated from Azure Share first then using that SAS token in URL to send http request to Azure Files Storage:

https://[yourshare].file.core.windows.net/[yourdirectory]/[yourfile]?[your_sas_token]

I have created a class to help client doing some basic operations as below (it is portable class so can use anywhere in client side):

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();
            }
        }
    }

In server side, use the following function to generate SAS token from 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        
            };
        }

Finally using class like this:

var azureFileRest = new AzureFileREST(sasToken);
await azureFileRest.CreateIfNotExist(directoryName);
await azureFileRest.UploadFile(directoryName + "/" + fileName, bytes);


来源:https://stackoverflow.com/questions/39275560/azure-file-share-rest-api-for-xamarin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!