2

In our project, we were using the Azure Storage 6.0.0 version and we were making use of the UploadTextAsync method to create blobs. After updating to the latest version, the UploadTextAsync function stopped working and now it throws an exception:

"Object reference not set to an instance of an object."

I've tried different methods to replace it but all throw the same exception. For example:

byte[] fileBytes = Encoding.UTF8.GetBytes(data);
await lockBlob.UploadFromByteArrayAsync(fileBytes, 0, fileBytes.Length);

The only way I made it work was to change to the synchronous version:

BlobRequestOptions blobOptions = new BlobRequestOptions
{
         MaximumExecutionTime = TimeSpan.FromSeconds(5),
};
lockBlob.UploadText(data, null, null, blobOptions, null);

How can I make the async version work? Is there a workaround? I really need the async version.

The UploadText (async and sync) method creates the blob if it doesn't already exist, and overwrites it if it does.

Why does it work with the sync version and not the async with the update?

For the blob creation this is the code:

var container= client.GetContainerReference("lockblobs");
await container.CreateIfNotExistsAsync();
var lockBlob = container.GetBlockBlobReference(data);
est.tenorio
  • 193
  • 2
  • 7
  • 2
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – MickyD May 22 '18 at 23:59
  • 2
    Where did you instantiate `lockBlob`? You didn't post that code – Camilo Terevinto May 23 '18 at 00:00

1 Answers1

2

SOLVED:

After debugging through the callstack inside the Azure package it turns out that there's a check in the BlobRequestOptions, by default there's a mismatch between the RequireEncryption and EncryptionPolicy.

This is the culprit inside the BlobRequestOptions definition:

internal void AssertPolicyIfRequired()
{
    if (this.RequireEncryption.HasValue && this.RequireEncryption.Value && this.EncryptionPolicy == null)
    {
          throw new InvalidOperationException(SR.EncryptionPolicyMissingInStrictMode);
    }
}

in https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Blob/BlobRequestOptions.cs

So basically by doing:

BlobRequestOptions blobOptions = new BlobRequestOptions
{
    MaximumExecutionTime = TimeSpan.FromSeconds(5),
    ParallelOperationThreadCount = 48,
    RequireEncryption = false
};

await lockBlob.UploadTextAsync(data, null, null, blobOptions, null);

I avoid the check in the AssertPolicyIfRequired check. So bottom line, set RequireEncryption = false or set it to true and also defining a proper Encryption Policy.

This now makes work all the Upload****Async methods.

Here is the callstack that helped me to debug the issue:

{"ClassName":"System.NullReferenceException","Message":"Object reference not set to an instance of an object.","Data":null,"InnerException":null,"HelpURL":null,"StackTraceString":"   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.<>c__DisplayClass1d.b__f(Action continuation) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 620
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.BeginUploadFromStreamHelper(Stream source, Nullable`1 length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, Object state) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 665
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.BeginUploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, AsyncCallback callback, Object state) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 477
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.BeginUploadFromByteArray(Byte[] buffer, Int32 index, Int32 count, AsyncCallback callback, Object state) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 1146
   at Microsoft.WindowsAzure.Storage.Core.Util.AsyncExtensions.TaskFromVoidApm[T1,T2,T3](Func`6 beginMethod, Action`1 endMethod, T1 arg1, T2 arg2, T3 arg3, CancellationToken cancellationToken) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Util\AsyncExtensions.cs:line 210
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromByteArrayAsync(Byte[] buffer, Int32 index, Int32 count, CancellationToken cancellationToken) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 1204
   at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromByteArrayAsync(Byte[] buffer, Int32 index, Int32 count) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 1190
est.tenorio
  • 193
  • 2
  • 7
  • Great! You could accept your answer for others to refer. And in a console app I can't reproduce your problem. The `RequireEncryption` is false by default as described in method remarks. And once I set it to true without policy defined, exception is `Encryption Policy is mandatory when RequireEncryption is set to true. If you do not want to encrypt/decrypt data, please set RequireEncryption to false in request options`. Is it possible it's caused by other settings/code in your project? – Jerry Liu May 24 '18 at 05:42