Azure File Share REST API for Xamarin

前端 未结 1 1424
無奈伤痛
無奈伤痛 2021-01-27 17:09

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 Win

相关标签:
1条回答
  • 2021-01-27 17:32

    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);
    
    0 讨论(0)
提交回复
热议问题