proteus
proteus

Reputation: 555

Saving a MemoryStream to Azure blob storage

I'm using the Infragistics report system to create reports as PDFs and save them to Azure Blob Storage but I'm having trouble getting it to work. I generate the report as a Report object without any problems. This object has a method called Publish which publishes the report to a stream in a specified file format, which in my case is PDF. When the code attempts to Upload from the stream, I get this error

Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (400) Bad Request

I have no idea what's causing this, the error message doesn't actually give me much to work on. I'm using local storage while I'm developing, this all seems to be working fine (I can store images without any problems). This is the method that's crashing out

public async Task<CloudBlockBlob> UploadAndSaveReportAsPDFToBlobAsync(Report report, EnumHelper.Reports reportName, string containerName)
{
    chpBlobContainer = blobClient.GetContainerReference(containerName);
    string blobName = Guid.NewGuid().ToString() + Path.GetExtension(reportName.GetDescription());
    // Retrieve reference to a blob. 
    CloudBlockBlob reportBlob = chpBlobContainer.GetBlockBlobReference(blobName);
    using (Stream stream = new MemoryStream())
    {
        try
        {
            report.Publish(stream, FileFormat.PDF);
        }
        catch(Exception ex)
        {
            //
        }

        await reportBlob.UploadFromStreamAsync(stream);
    }
    return reportBlob;
}

and this is a bit more of the error message

Exception while executing function: Functions.ProcessQueueMessage Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> 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, StorageCommandBase1 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.CloudBlockBlob.<>c__DisplayClass42.<PutBlobImpl>b__41(RESTCommand1 cmd, HttpWebResponse resp, Exception ex, OperationContext ctx) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlockBlob.cs:line 2339 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 ---

Anyone have any advice ?

I've updated my connection code on the constructor of my blob service, it now looks like this, but it still doesn't work and fiddler gives me this

CONNECT localhost:10000 HTTP/1.1 Host: localhost:10000

HTTP/1.1 200 Connection Established FiddlerGateway: Direct StartTime: 14:23:33.061 Connection: close EndTime: 14:23:33.063 ClientToServerBytes: 125 ServerToClientBytes: 505

but its http, my connection specified https, Im still none the wiser

public BlobService()
    {
        var storageCredentials = new StorageCredentials("devstoreaccount1", "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==");
        var blobEndpoint = new Uri("https://localhost.fiddler:10000");
        var queueEndpoint = new Uri("https://localhost.fiddler:10001");
        var tableEndpoint = new Uri("https://localhost.fiddler:10002");
        var storageAccount = new CloudStorageAccount(storageCredentials, blobEndpoint, queueEndpoint, tableEndpoint, null);
        var blobClient = storageAccount.CreateCloudBlobClient();
        chpBlobContainer = blobClient.GetContainerReference("CHPReports");
        if (chpBlobContainer.CreateIfNotExists())
        {
            // Enable public access on the newly created "images" container.
            chpBlobContainer.SetPermissions(
                new BlobContainerPermissions
                {
                    PublicAccess = BlobContainerPublicAccessType.Blob
                });
        }
    }

Upvotes: 0

Views: 2596

Answers (1)

jle
jle

Reputation: 9489

You cannot use "CHPReports" as the container name as the name must be lowercase.

Make sure the container name is valid:

A container name must be a valid DNS name, conforming to the following naming rules: Container names must start with a letter or number, and can contain only letters, numbers, and the dash (-) character. Every dash (-) character must be immediately preceded and followed by a letter or number; consecutive dashes are not permitted in container names. All letters in a container name must be lowercase. Container names must be from 3 through 63 characters long.

Upvotes: 3

Related Questions