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

Azure Functions中Activity返回IEnumerable<IListBlobItem>调用序列化报错

问题分析与解决方案

这个报错的核心原因很明确:Durable Functions 在 Activity 和 Orchestrator 之间传递数据时需要序列化对象,但 IListBlobItem 是一个接口,JSON 序列化器无法实例化接口类型,所以才会抛出"无法创建接口实例"的错误。

要解决这个问题,我们需要把接口类型转换成可序列化的具体数据结构,具体步骤如下:


1. 创建可序列化的 Blob 信息 DTO

首先定义一个简单的数据传输对象(DTO),只保留你业务需要的 Blob 关键属性,比如名称、URI、是否为目录:

public class BlobInfo
{
    public string Name { get; set; }
    public string Uri { get; set; }
    public bool IsDirectory { get; set; }
}

2. 修改 Activity 函数返回 DTO 集合

把原来返回 IEnumerable<IListBlobItem> 的逻辑,改成将 Blob 项转换成 BlobInfo 实例并返回:

[FunctionName("process_file_GetBlobList")]
public static IEnumerable<BlobInfo> GetBlobList([ActivityTrigger] string name, ILogger log) {
    string storageConnectionString = @"connstring";
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference("container");
    
    var blobInfos = new List<BlobInfo>();

    // 遍历根目录的所有项
    foreach (IListBlobItem blobItem in container.ListBlobs()) {
        if (blobItem is CloudBlobDirectory directory) {
            // 递归遍历子目录下的所有项
            foreach (var subItem in directory.ListBlobs(true)) {
                AddBlobInfo(subItem, blobInfos);
            }
        } else if (blobItem is CloudBlockBlob blob) {
            AddBlobInfo(blob, blobInfos);
        }
    }

    return blobInfos;
}

// 提取重复的转换逻辑到辅助方法
private static void AddBlobInfo(IListBlobItem item, List<BlobInfo> blobInfos)
{
    if (item is CloudBlockBlob blob)
    {
        blobInfos.Add(new BlobInfo
        {
            Name = blob.Name,
            Uri = blob.Uri.ToString(),
            IsDirectory = false
        });
    }
    else if (item is CloudBlobDirectory dir)
    {
        blobInfos.Add(new BlobInfo
        {
            Name = dir.Prefix,
            Uri = dir.Uri.ToString(),
            IsDirectory = true
        });
    }
}

3. 修改 Orchestrator 调用的类型

将 Orchestrator 中的调用类型换成我们定义的 BlobInfo:

IEnumerable<BlobInfo> blobs = await context.CallActivityAsync<IEnumerable<BlobInfo>>("process_file_GetBlobList", null);

为什么要这么做?

Durable Functions 的 Activity 和 Orchestrator 之间通过序列化/反序列化传递数据,默认使用 JSON.NET 处理。接口、抽象类或者带有复杂未序列化属性的对象(比如 IListBlobItem 包含的流操作属性)都无法被正确序列化。通过自定义 DTO,我们既规避了序列化问题,又只传递业务需要的核心数据,减少了数据传输量。

内容的提问来源于stack exchange,提问作者Kaja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:27:04