You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Azure Function App将FTP文件存入Azure存储账户,本地运行报错求助

Azure Function本地运行报错排查

我刚接触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。


问题排查与修正方向

  1. 存储连接字符串格式错误
    你使用的是SAS URL,而非标准存储账户连接字符串,CloudStorageAccount.Parse无法解析这种格式。若使用SAS URL,需直接通过BlobContainerClient构造函数传入;若要用CloudStorageAccount,需使用标准连接字符串:DefaultEndpointsProtocol=https;AccountName=mystorageaccount;AccountKey=yourAccountKey;EndpointSuffix=core.windows.net。

  2. 冗余的Base64转换操作
    将XML文档保存到内存流后,无需转成字符串再转Base64,直接使用内存流上传即可,多余转换可能引发格式错误。

  3. GetXmlDocument方法未实现
    代码中调用的GetXmlDocument()缺少具体实现,FTP下载逻辑(地址、凭据、文件路径)若配置错误,会直接抛出异常,需补全该方法并验证FTP连接有效性。

  4. local.settings.json配置格式问题
    确保所有配置参数都在Values节点下,正确格式示例:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "AzureWebJobsSecretStorageType": "Files"
      }
    }
    
  5. 升级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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:07:33