从Azure Function App将FTP文件存入Azure存储账户,本地运行报错求助
我刚接触Azure Function Apps,编写了如下代码用于从FTP服务器下载文件并上传至Azure存储账户:
[FunctionName("UploadBlobFunction")] public static async Task<IActionResult> Runn( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log) { string fileName = ""; try { string storageConnectionString = "https://mystorageaccount.blob.core.windows.net/mycontainer?sp=r&st=2024-07-11T06:09:32Z&se=2025-05-01T14:09:32Z&sv=2022-11-02&sr=c&sig=ObUpZOmxWAVqmrbWc0X52xbSRMf8XUc%2BGau2esCzlDE%3D"; string containerName = "mycontainer"; CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference(containerName); // Create the container if it doesn't exist await container.CreateIfNotExistsAsync(); // Get a reference to a blob in the container string directoryName = "Backups"; CloudBlobDirectory directory = container.GetDirectoryReference(directoryName); // Get the file name from the request fileName = "one.xml"; XmlDocument xmlDoc = GetXmlDocument(); ///Gets the XmlDocument from FTP MemoryStream xmlStream = new MemoryStream(); xmlDoc.Save(xmlStream); xmlStream.Position = 0; // Retrieve the file from the request body var requestBody = await new StreamReader(xmlStream).ReadToEndAsync(); byte[] fileBytes = Convert.FromBase64String(requestBody); // Upload the file to Azure Blob Storage CloudBlockBlob blob = directory.GetBlockBlobReference(fileName); using (var stream = new MemoryStream(fileBytes)) { await blob.UploadFromStreamAsync(stream); } } catch (Exception ex) { log.LogError($"Error downloading file from FTP: {ex.Message}"); return new StatusCodeResult(StatusCodes.Status500InternalServerError); } return new OkObjectResult($"File uploaded successfully: {fileName}"); }
本地运行代码时控制台出现报错,已尝试在local.settings.json中添加参数AzureWebJobsSecretStorageType:"Files",但仍显示相同错误,目前尚未将代码发布至Azure。
问题排查与修正方向
存储连接字符串格式错误
你使用的是SAS URL,而非标准存储账户连接字符串,CloudStorageAccount.Parse无法解析这种格式。若使用SAS URL,需直接通过BlobContainerClient构造函数传入;若要用CloudStorageAccount,需使用标准连接字符串:DefaultEndpointsProtocol=https;AccountName=mystorageaccount;AccountKey=yourAccountKey;EndpointSuffix=core.windows.net。冗余的Base64转换操作
将XML文档保存到内存流后,无需转成字符串再转Base64,直接使用内存流上传即可,多余转换可能引发格式错误。GetXmlDocument方法未实现
代码中调用的GetXmlDocument()缺少具体实现,FTP下载逻辑(地址、凭据、文件路径)若配置错误,会直接抛出异常,需补全该方法并验证FTP连接有效性。local.settings.json配置格式问题
确保所有配置参数都在Values节点下,正确格式示例:{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "dotnet", "AzureWebJobsSecretStorageType": "Files" } }升级Blob存储SDK
旧版WindowsAzure.Storage包已停止维护,建议替换为最新的Azure.Storage.Blobs包,使用新API简化操作。
修正后的代码示例(基于新SDK)
[FunctionName("UploadBlobFunction")] public static async Task<IActionResult> Runn( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log) { string fileName = ""; try { string sasUrl = "https://mystorageaccount.blob.core.windows.net/mycontainer?sp=r&st=2024-07-11T06:09:32Z&se=2025-05-01T14:09:32Z&sv=2022-11-02&sr=c&sig=ObUpZOmxWAVqmrbWc0X52xbSRMf8XUc%2BGau2esCzlDE%3D"; BlobContainerClient containerClient = new BlobContainerClient(new Uri(sasUrl)); await containerClient.CreateIfNotExistsAsync(); string directoryName = "Backups"; string blobPath = $"{directoryName}/one.xml"; BlobClient blobClient = containerClient.GetBlobClient(blobPath); fileName = "one.xml"; XmlDocument xmlDoc = GetXmlDocument(); // 补全FTP下载逻辑 using (MemoryStream xmlStream = new MemoryStream()) { xmlDoc.Save(xmlStream); xmlStream.Position = 0; await blobClient.UploadAsync(xmlStream, overwrite: true); } } catch (Exception ex) { log.LogError($"Error processing file: {ex.Message}\n{ex.StackTrace}"); return new StatusCodeResult(StatusCodes.Status500InternalServerError); } return new OkObjectResult($"File uploaded successfully: {fileName}"); }
内容的提问来源于stack exchange,提问作者sukesh

