0
votes

I have had some issues with upgrading a MobileService to Azure App Service. I had the following question Blob storage access from Azure App Service which enabled me to access the blob storage. Now I wanted to save an image to the blob storage, which the updated code is like this:

string cloud = "";

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("battlecrestimage_AzureStorageConnectionString"));
cloud = storageAccount.BlobEndpoint.ToString() + "        " + storageAccount.BlobStorageUri.ToString();

// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
if (item.ContainerName != null)
 {
     // Set the BLOB store container name on the item, which must be lowercase.
     item.ContainerName = item.ContainerName.ToLower();

     // Create a container, if it doesn't already exist.
     CloudBlobContainer container = blobClient.GetContainerReference(item.ContainerName);

     try
     {
          await container.DeleteIfExistsAsync();
          telemetry.TrackTrace("Deleted.");
     }
     catch 
     {
          telemetry.TrackTrace("Could not DeleteIfExist.");
     }
     await container.CreateIfNotExistsAsync(); //Code fails at this point

     // Create a shared access permission policy. 
     BlobContainerPermissions containerPermissions = new BlobContainerPermissions();

     // Enable anonymous read access to BLOBs.
     containerPermissions.PublicAccess = BlobContainerPublicAccessType.Blob;
     container.SetPermissions(containerPermissions);

     // Define a policy that gives write access to the container for 5 minutes.                                   
     SharedAccessBlobPolicy sasPolicy = new SharedAccessBlobPolicy()
     {
         SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(5),
         Permissions = SharedAccessBlobPermissions.Write
     };

     // Get the SAS as a string.
     item.SasQueryString = container.GetSharedAccessSignature(sasPolicy);

     // Set the URL used to store the image.
     item.ImageUri = string.Format("{0}{1}/{2}", storageAccount.BlobEndpoint,
     item.ContainerName, item.ResourceName);
}

I cannot understand why the code fails at await container.CreateIfNotExistsAsync();. Can somebody clarify how the correct way is to create the blob storage and uri? To return this to a client.

Update

Here is the stack-output from the diagnostic overview.

Operation=blobStorageCreationController.ExecuteAsync, Exception=Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request. at Microsoft.WindowsAzure.Storage.Shared.Protocol.HttpResponseParsers.ProcessExpectedStatusCodeNoException[T](HttpStatusCode expectedStatusCode, HttpStatusCode actualStatusCode, T retVal, StorageCommandBase 1 cmd, Exception ex) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\Common\Shared\Protocol\HttpResponseParsers.Common.cs:line 50 at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.b__34(RESTCommand 1 cmd, HttpWebResponse resp, Exception ex, OperationContext ctx) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlobContainer.cs:line 2620 at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.EndGetResponse[T](IAsyncResult getResponseResult) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:line 299 --- End of inner exception stack trace --- at Microsoft.WindowsAzure.Storage.Core.Util.StorageAsyncResult 1.End() in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Util\StorageAsyncResult.cs:line 77 at Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.EndCreateIfNotExists(IAsyncResult asyncResult) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlobContainer.cs:line 381 at Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.<>c__DisplayClass1 1.b__0(IAsyncResult ar) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Util\AsyncExtensions.cs:line 66 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at BCAppService.Controllers.blobStorageCreationController.d__1.MoveNext() in C:\BCApp_Runtime\BCAppService\Controllers\blobStorageController.cs:line 248

There does not exist a blob at the time of creation.

1
could you say the name of the container you are trying to create?Alex Belotserkovskiy
check this article: stackoverflow.com/questions/19599819/… to see if that is your issue.Alex Chen-WX
@AlexBelotserkovskiy it was as you said the name. After upgrading the service I had changed the Id from an int to a string. The string had a _ which was the issue. I will delete the question tomorrow, as this does not contribute anything.JTIM

1 Answers

2
votes

Did the blob container already exist upon running this code snippet?

If so, you must know that the delete operation is not an instant operation. Once the delete request is issued, the table container is marked for deletion by the storage service and shall be no longer accessible. It will be deleted by the garbage collector later on. If this is the case you should get a 409 (conflict) error in the marked line.