Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload files to Azure Blob storage through WebApi without accessing local filesystem

I'm trying to upload files from local command line client to Azure storage through web-api. I'm using Azure Web-Site for that. Working with the client is not a problem. And I've got everything working locally fine. Here is the web-api code:

    public async Task<HttpResponseMessage> PostUpload()
    {
        // need a local resource to store uploaded files temporarily
        LocalResource localResource = null;
        try
        {
            // Azure web-site fails here
            localResource = RoleEnvironment.GetLocalResource("TempStorage");
        }
        catch (Exception e)
        {
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Unable to get access to local resources");
        }

        var provider = new MultipartFormDataStreamProvider(localResource.RootPath);

        // Read the form data.
        await Request.Content.ReadAsMultipartAsync(provider);

        // snipped validation code
        var container = // code to get container

        foreach (var fileData in provider.FileData)
        {
            var filename = GetBlobName(fileData);
            var blob = container.GetBlockBlobReference(filename);
            using (var filestream = File.OpenRead(fileData.LocalFileName))
            {
                blob.UploadFromStream(filestream);
            }
            File.Delete(fileData.LocalFileName);
        }

        return Request.CreateResponse(HttpStatusCode.OK);
    }

Everything works fine when I run locally, but as soon as I deploy web-site in Azure, I can't upload, because Azure Web-Sites don't have access to LocalResource. And I'll need to switch to Azure Web-Role. I can switch, but accessing local file system is bothering me all together.

And LocalResource is required for instance of MultipartFormDataStreamProvider(). And I have not found alternative ways to upload files to WebApi. My plan was to channel through upload directly to Azure, without storing anything on a local HDD.

Is there any other way to upload files?

p.s. I have seen usages of Shared Access Signatures where I can give client application a url with signature and let the client upload directly to Azure Blog. But I'm not sure about how secure that is going to be and not really comfortable (yet) with passing the signatures down to the client. At the moment I presume the client is going to be run in very hostile environment and nothing can be trusted coming back from the client.

UPD My final solution involved using write only Shared Access Signature issued on the server and passed down to the client. And client then uploads files directly to Azure. This way I save a lot of hassle with managing uploaded files. And here is more detailed description of my solution.

like image 508
trailmax Avatar asked Jun 03 '13 13:06

trailmax


1 Answers

This isn't exactly the answer you are looking for, but you can use local storage with Azure Websites using MultiPartFileStreamProvider and Path.GetTempPath(). The code would look something like this

public async Task<HttpResponseMessage> PostUpload()
{
    var provider = new MultipartFileStreamProvider(Path.GetTempPath());

    // Read the form data.
    await Request.Content.ReadAsMultipartAsync(provider);

    // do the rest the same     
}
like image 194
Daniel Auger Avatar answered Sep 19 '22 10:09

Daniel Auger