使用C#调用SharePoint REST API创建文件夹时遇400/500错误
- 已通过REST API实现文件上传、下载及目录浏览操作,但创建文件夹时持续返回400错误请求,偶尔出现500内部服务器错误
- 相同请求在Postman中可成功执行
正确请求格式
POST https://{site_url}/_api/web/folders Authorization: "Bearer " + accessToken Accept: "application/json;odata=verbose" Content-Type: "application/json" Content-Length: {length of request body as integer} X-RequestDigest: "{form_digest_value}" { "__metadata": { "type": "SP.Folder" }, "ServerRelativeUrl": "/document library relative url/folder name" }
你的C#代码
private async Task<HttpResponseMessage> PostFolderSharePoint(string url, string serverRelativeUrl) { string accessToken = GetAccessToken().GetAwaiter().GetResult(); string jsoncontent = JsonConvert.SerializeObject("{\"__metadata\": {\"type\": \"SP.Folder\"},\"ServerRelativeUrl\": serverRelativeUrl}"); var content = new StringContent(jsoncontent, Encoding.UTF8, "application/json"); var FormDiGestValue = await GetFormDigestValue(accessToken); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var requestMessage = new HttpRequestMessage(HttpMethod.Post,url) { Content = content }; requestMessage.Headers.Add("X-RequestDigest", FormDiGestValue); HttpResponseMessage response = await _httpClient.SendAsync(requestMessage).ConfigureAwait(false); return response; }
问题排查与修复
1. JSON序列化错误
你直接对包含变量的字符串进行序列化,导致serverRelativeUrl变量未被替换,且最终JSON被双重转义,格式完全错误。
修复:创建匿名对象再序列化,确保变量被正确注入:
var folderData = new { __metadata = new { type = "SP.Folder" }, ServerRelativeUrl = serverRelativeUrl }; string jsoncontent = JsonConvert.SerializeObject(folderData);
2. 请求头缺失odata=verbose
正确请求要求Accept头为application/json;odata=verbose,但你的代码只添加了application/json,这会导致SharePoint返回不符合预期的响应格式。
修复:修改Accept头设置:
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json;odata=verbose"));
3. 同步阻塞调用风险
使用GetAccessToken().GetAwaiter().GetResult()可能导致死锁,建议改用await:
string accessToken = await GetAccessToken();
4. HttpClient复用问题(可能引发500错误)
如果_httpClient是全局复用实例,之前的请求头可能残留导致冲突。建议在每次请求时创建新实例(或确保头被正确重置):
using (var httpClient = new HttpClient()) { // 在此配置请求头和发送请求 }
修复后的完整代码
private async Task<HttpResponseMessage> PostFolderSharePoint(string url, string serverRelativeUrl) { string accessToken = await GetAccessToken(); var folderData = new { __metadata = new { type = "SP.Folder" }, ServerRelativeUrl = serverRelativeUrl }; string jsoncontent = JsonConvert.SerializeObject(folderData); var content = new StringContent(jsoncontent, Encoding.UTF8, "application/json"); string formDigestValue = await GetFormDigestValue(accessToken); using (var httpClient = new HttpClient()) { httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json;odata=verbose")); var requestMessage = new HttpRequestMessage(HttpMethod.Post, url) { Content = content }; requestMessage.Headers.Add("X-RequestDigest", formDigestValue); return await httpClient.SendAsync(requestMessage).ConfigureAwait(false); } }
内容的提问来源于stack exchange,提问作者secretunfunnyguy
相关产品推荐
相关产品推荐

