WebDAV在C#中无原生File类支持,需通过HTTP协议层操作;推荐使用Portable.WebDavClient库,支持Basic Auth、目录列表、上传下载等基础功能,但不封装LOCK/UNLOCK、断点续传及OAuth2。

WebDAV 在 C# 中没有原生 File 类等价物
别指望 File.Copy、Directory.GetFiles 这类方法能直接对 WebDAV URL 起作用——.NET 标准库不支持把 https://dav.example.com/ 当作本地路径传进去。所有操作必须走 HTTP 协议层,手动构造或委托给支持 WebDAV 的客户端库。
推荐用 Portable.WebDavClient 库封装底层细节
它比裸写 HttpClient + XML 解析更可靠,且兼容主流 WebDAV 服务(Nextcloud、OwnCloud、IIS WebDAV、SharePoint)。安装 NuGet 包:Install-Package Portable.WebDavClient
基本读写示例:
var client = new WebDavClient(new Uri("https://dav.example.com/"), "user", "pass");
// 上传
await client.PutAsync("/test.txt", new MemoryStream(Encoding.UTF8.GetBytes("hello webdav")));
// 下载
using var stream = await client.GetAsync("/test.txt");
// 列目录(返回 WebDavItem[])
var items = await client.ListAsync("/");
- 注意路径必须以
/开头,且不带主机名 - 认证失败时抛出
WebDavException,不是通用HttpRequestException - 不支持通配符或递归删除,
ListAsync默认只返回一级内容
自定义 HttpClient 时必须显式设置 WebDAV 方法和头
如果不用封装库,自己发请求要特别注意协议细节:
-
PROPFIND方法用于列目录,Body 必须是 XML,且Content-Type: application/xml -
PUT上传前需确保服务器允许,有些服务要求先HEAD检查是否存在再PUT - 务必设置
client.DefaultRequestHeaders.Authorization,Basic Auth 最常用:Convert.ToBase64String(Encoding.ASCII.GetBytes("user:pass")) - IIS WebDAV 默认禁用
PROPFIND,需在服务器端开启“WebDAV 授权规则”
文件锁、断点续传、大文件上传需额外处理
WebDAV 协议本身支持 LOCK/UNLOCK 和 Range 请求,但 Portable.WebDavClient 不提供高层封装。遇到以下情况得自己补逻辑:
- 并发写入冲突:先
LOCK,操作完UNLOCK,否则可能被其他客户端覆盖 - 上传超时:对大文件用分块
PUT+Content-Range,并捕获HttpRequestException做重试 - 某些服务(如 SharePoint Online)要求使用 OAuth2,而非 Basic Auth,此时必须集成
Microsoft.Identity.Client
真正难的不是“怎么传”,而是服务端配置差异和边界错误处理——比如 403 Forbidden 可能是权限不足,也可能是未启用 WebDAV 模块,还可能是反向代理(Nginx/Apache)截断了 PROPFIND 请求。










