Reputation: 175
I am trying to read a text file from Blob Storage using a Azure Function App. My goal is to read the file, which is a CSV, and reformat it into a new CSV with additional details added that isn't in the original CSV file.
I keep getting the following compilation error:
2018-11-28T00:22:34.125 [Error] run.csx(60,19): error CS1061: 'CloudBlockBlob' does not contain a definition for 'DownloadToStream' and no extension method 'DownloadToStream' accepting a first argument of type 'CloudBlockBlob' could be found (are you missing a using directive or an assembly reference?)
I can copy the Blob Storage section of the code into a Console Application's project and it will compile just fine.
Am I missing a reference?
This is the full function minus the connection string for the Blob Storage.
#r "Newtonsoft.Json"
#r "System.Configuration"
#r "System.Data"
#r "System.Collections"
#r "System.IO.Compression"
#r "System.Net"
#r "Microsoft.WindowsAzure.Storage"
#r "System.Linq"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Configuration;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Data;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System.Linq;
using System.Threading.Tasks;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string filePath = req.Query["filePath"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
filePath = filePath ?? data?.filePath;
var fileInfo = GetFileInfo(filePath);
string line = "";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("Connection String goes Here");
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = client.GetContainerReference(fileInfo.Container);
var fileNameWithFolder =
fileInfo.DirectoryName == ""
? fileInfo.FileName
: $"{fileInfo.DirectoryName}/{fileInfo.FileName}";
CloudBlockBlob blockBlob2 = container.GetBlockBlobReference(fileNameWithFolder);
using (var memoryStream = new MemoryStream())
{
try
{
blockBlob2.DownloadToStream(memoryStream);
line = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
}
catch (Exception ex)
{
line = ex.Message;
}
}
return filePath != null
? (ActionResult)new OkObjectResult($"filePath: {filePath} Container: {fileInfo.Container} DirectoryName: {fileInfo.DirectoryName} FileName: {fileInfo.FileName}*********{line}")
: new BadRequestObjectResult("Please pass a filePath on the query string or in the request body");
}
private static FileInfo GetFileInfo(string filePath)
{
int index = filePath.IndexOf("/");
filePath = (index < 0)
? filePath
: filePath.Remove(index, 1);
var filePathSplit = filePath.Split('/');
var fileInfo = new FileInfo();
fileInfo.Container = filePathSplit[0];
if ((filePathSplit.Length - 2) > 0)
{
var folderName = "";
for(var i = 1; i < filePathSplit.Length - 1; i++)
{
if (folderName.Trim().Length > 0)
{
folderName += "/";
}
folderName += filePathSplit[i];
}
fileInfo.DirectoryName = folderName;
}
fileInfo.FileName = filePathSplit[filePathSplit.Length - 1];
return fileInfo;
}
public class FileInfo
{
public string Container { get; set; }
public string DirectoryName { get; set; }
public string FileName { get; set; }
}
Upvotes: 3
Views: 8429
Reputation: 17800
V2 function is based on .Net Core env hence it references Microsoft.WindowsAzure.Storage
assembly depending on .Net Standard, which has no synchronous API, it means we need *Async method.
await blockBlob2.DownloadToStreamAsync(memoryStream);
Upvotes: 5
Reputation: 23141
According to your code and error message, you did not use the method DownloadToStream correctly. For more details, please refer to the document.
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
var blobRequestOptions = new BlobRequestOptions
{
ServerTimeout = TimeSpan.FromSeconds(30),
MaximumExecutionTime = TimeSpan.FromSeconds(120),
RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(3), maxRetryCount),
};
using (var memoryStream = new MemoryStream())
{
blockBlob.DownloadToStream(memoryStream, null, blobRequestOptions);
}
Upvotes: 0