ftp协议本身不支持上传预览,所谓“预览”实为本地读取或上传后校验;上传失败主因是路径拼接错误、工作目录与权限不匹配,必须用绝对路径并确保服务器目标目录可写。

FTP 文件上传本身不支持“预览”——这是常见误解,C# 的 FtpWebRequest 或 WebClient 只能上传完整文件,无法边传边预览内容;所谓“预览”,实际是上传前本地读取或上传后立即下载校验,不是 FTP 协议能力。
为什么 FtpWebRequest 上传后文件为空或报 550 错误
根本原因常是路径拼接错误或权限/工作目录未对齐。FTP 服务器(尤其 IIS、FileZilla Server)默认工作目录 ≠ 根目录,FtpWebRequest 的 RequestUri 必须是**绝对路径**,且需与目标目录权限匹配。
-
ftp://server.com/uploads/file.txt是合法 URI;但若服务器实际只允许写入/wwwroot/uploads/,而你传到/uploads/,就会 550 Access denied - 使用
ftp://server.com//uploads/file.txt(双斜杠)会触发某些服务器解析异常,应避免 - 上传前未调用
request.UseBinary = true,文本模式上传二进制文件(如图片、PDF)会导致损坏 - IIS FTP 默认禁用
STOR命令写入根目录,必须明确指定子目录并确保该目录开启写权限
如何在上传前“模拟预览”内容(非真正 FTP 预览)
所谓“上传预览”,本质是本地验证:确认文件可读、大小合理、格式符合预期,再发起上传。这不是 FTP 功能,而是业务逻辑前置检查。
- 用
FileStream打开文件时加FileAccess.Read和FileShare.Read,避免上传中被其他进程锁住 - 上传前读取前 1024 字节做 MIME 类型推测(用
Path.GetExtension+ 白名单校验更可靠) - 大文件(>100MB)建议先用
new FileInfo(path).Length检查,避免上传中途因磁盘满失败 - 示例:判断是否为图片并读取宽高(需引用
System.Drawing.Common,注意 .NET 6+ Linux 下需安装 libgdiplus):using var img = Image.FromFile(path);<br>var isImage = img.Width > 0 && img.Height > 0;
WebClient 上传比 FtpWebRequest 更简单,但容易忽略超时和编码
WebClient 封装了底层细节,适合简单场景,但默认超时仅 100 秒,上传大文件必改;且 FTP 路径中的中文名需手动 Uri.EscapeDataString,否则 550。
- 必须设置:
client.Credentials = new NetworkCredential("user", "pass"),否则匿名登录失败 - 超时必须显式设:
client.Timeout = 300_000(5 分钟),单位毫秒 - 含中文的文件名必须处理:
string encodedName = Uri.EscapeDataString("测试.png"),再拼入 URL:ftp://s/ uploads/ + encodedName - 不支持断点续传,上传中断只能重来;
FtpWebRequest也无原生支持,需自己实现REST命令逻辑
FTP 协议本身没有“预览”语义,所有“上传预览”都是应用层折衷方案;最容易被忽略的是服务器端工作目录与权限映射关系——连通性测试成功不等于上传路径可用,务必用相同凭据手动登录 FTP 客户端(如 FileZilla),确认目标路径可写且路径拼写完全一致。











