调用SharePoint API创建文件夹时为何返回400 Bad Request错误?
问题描述
在C#应用中尝试创建SharePoint文件夹时,持续收到400 Bad Request响应,代码与网上示例一致,需排查问题原因。
用户代码如下:
public async Task CreateFolder(string folderName, MainWindow uiWindow) { string accessToken = null; using (var authenticationManager = new AuthenticationManager()) { accessToken = await authenticationManager.GetAccessToken(uiWindow); } using (HttpClient client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); var folderData = new { __metadata = new { type = "SP.Folder" }, ServerRelativeUrl = $"{_site}/{folderName}" }; var json = JsonConvert.SerializeObject(folderData); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await client.PostAsync($"{_site}/_api/web/folders", content); if (response.IsSuccessStatusCode) { Console.WriteLine("Folder created successfully."); } else { Console.WriteLine($"Error: {response.ReasonPhrase}"); } } }
可能的问题及解决方法
ServerRelativeUrl格式错误
SharePoint的ServerRelativeUrl要求是相对于网站集的完整层级路径。如果_site变量仅指向站点根路径(如/sites/MySite),直接拼接folderName会导致路径无效——正确路径应包含父文件夹(比如要在文档库下创建,需写成/sites/MySite/Documents/{folderName})。缺少X-RequestDigest请求头
SharePoint REST API的POST操作必须携带X-RequestDigest头防CSRF攻击,你的代码未添加该头,这是400错误的常见原因。需先通过GET请求获取该值:// 获取请求摘要 var digestResponse = await client.PostAsync($"{_site}/_api/contextinfo", null); var digestContent = await digestResponse.Content.ReadAsStringAsync(); var digestObj = JsonConvert.DeserializeObject<dynamic>(digestContent); string requestDigest = digestObj.FormDigestValue; // 添加到请求头 client.DefaultRequestHeaders.Add("X-RequestDigest", requestDigest);AccessToken权限或有效性问题
即便获取了AccessToken,也可能存在权限不足(无文件夹创建权限)、Token受众与目标站点不匹配的情况。可通过JWT解析工具查看Token内容,确认权限范围和目标站点是否对应。文件夹名称含非法字符
SharePoint文件夹名称禁止包含\ / : * ? " < > |等字符,若folderName包含此类字符,会直接返回400错误,需先对名称做非法字符过滤。metadata类型拼写错误
确认__metadata中的type值SP.Folder拼写正确(大小写敏感),部分特殊场景下可能需调整类型,但创建文件夹时SP.Folder是标准值。
内容的提问来源于stack exchange,提问作者MatthewHagemann

