最直接方式是用 httpclient 调用 ipfs http api(http://127.0.0.1:5001/api/v0/add),post multipart/form-data,字段名固定为 file;响应为 ndjson 流,需逐行读取解析 hash。

用 HttpClient 调用 IPFS API 上传文件最直接
IPFS 没有原生 C# SDK,所有上传都走 HTTP API(默认 http://127.0.0.1:5001/api/v0/add)。别找“C# IPFS 包”,90% 是过时或封装了不维护的底层库,反而增加调试成本。
常见错误现象:400 Bad Request 或空响应体,大概率是没设对 Content-Type 或 multipart boundary;404 Not Found 说明本地节点没跑,或端口被改过。
- 确保
ipfs daemon已启动(命令行运行后看到Daemon is ready) - POST 请求必须用
multipart/form-data,不能用 JSON body -
HttpClient实例建议复用(别每次 new),但记得设置Timeout(IPFS 上传大文件可能卡住) - 上传单个文件时,表单字段名固定为
file,不是data或blob
var client = new HttpClient();
var content = new MultipartFormDataContent();
content.Add(new ByteArrayContent(File.ReadAllBytes("photo.jpg")), "file", "photo.jpg");
var response = await client.PostAsync("http://127.0.0.1:5001/api/v0/add", content);
add 返回的 Hash 是唯一访问地址
成功响应是纯文本流(不是 JSON),每行一个对象,上传单文件时只有一行,格式如:{"Name":"photo.jpg","Hash":"QmXyZ...abc123","Size":"24562"}。别直接 response.Content.ReadAsStringAsync() 后 JSON 解析——它不是标准 JSON 数组,而是 NDJSON(换行分隔的 JSON)。
使用场景:你需要拿这个 Hash 拼出网关链接,比如 https://ipfs.io/ipfs/QmXyZ...abc123,或者发给前端做去中心化引用。
- 解析时用
response.Content.ReadAsStream()+StreamReader.ReadLine()逐行读,避免大文件响应撑爆内存 -
Hash值区分大小写,且Qm开头是 v0 格式(当前主流),别手动截断或补零 - 如果上传的是文件夹,返回多行,第一行是根目录 Hash,后续是子项——但 C# 里更推荐先压缩再传单文件,省去路径解析逻辑
大文件上传要处理分块和进度,不是加个 Progress<long></long> 就行
HttpClient 的 IProgress<long></long> 只能报已写入请求体的字节数,不是已上链的字节数。IPFS 节点收到文件后还要 DAG 构建、分块、网络广播,这部分你完全感知不到。用户以为“进度条到 100% 就传完了”,实际可能卡在本地节点分块阶段。
性能影响:100MB 文件默认被切成 ~256KB 块,构建 DAG 可能吃光 1GB 内存;Windows 上若用 WSL2 运行 IPFS,跨虚拟机 IO 会进一步拖慢。
- 上传前用
FileInfo.Length判断是否 >50MB,超了就提示“可能需数分钟”,别隐藏耗时 - 不要依赖
HttpClient.Timeout做上传超时判断——它只管连接和发送完成,不管节点处理完没 - 真要监控进度,只能轮询
/api/v0/blocks/stat?arg=Qm...看块是否存在,但频繁查会加重节点负担
跨平台部署时,127.0.0.1 和 CORS 是两个独立坑
本地开发用 http://127.0.0.1:5001 没问题,但部署到 Linux 服务器或 Docker,IPFS 默认只监听 127.0.0.1,外部 C# 服务(比如 ASP.NET Core 容器)连不上。这不是代码问题,是 IPFS 配置问题。
错误现象:Connection refused;或上传成功但返回空 Hash——其实是请求发到了别的服务(比如 Nginx)。
- 改 IPFS 监听地址:运行
ipfs config Addresses.API "/ip4/0.0.0.0/tcp/5001",再重启 daemon - 别开
Access-Control-Allow-Origin: *(IPFS API 不支持 CORS,加了也没用),C# 后端调用不涉及浏览器同源限制 - Docker 场景下,C# 容器要用
host.docker.internal(Mac/Win)或宿主真实 IP(Linux)访问 IPFS,不能写localhost
Hash 本身没生命周期,但节点不 pin 就可能被 GC 清掉;自动 pin 要额外调 /api/v0/pin/add,而且得自己处理失败重试——这点容易漏,传完就以为万事大吉了。










