我试图使用HTTPClient和REST在SP2013中创建一个文件夹。
以下是要求&应用程序的约束
-
我需要使用REST在2013年文档库中创建一个文件夹。
-
程序必须是c#控制台应用程序
-
我必须只使用HTTPClient来调用web服务。
-
集成认证是必须的。你不能在代码中输入你的用户名和密码。它必须使用进程的标识
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Formatting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace RESTCreateFolder
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
int retVal = p.Process().Result;
}
private async Task<int> Process()
{
string url = "http://bi.abhi.com/testweb/";
using (HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new System.Uri(url);
client.DefaultRequestHeaders.Add("Accept", "application/json; odata=verbose");
string digest = await GetDigest(client);
Console.WriteLine("Digest " + digest);
try
{
await CreateFolder(client, digest);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
return 0;
}
private object CreateRequest(string folderPath)
{
var type = new { type = "SP.Folder" };
var request = new { __metadata = type, ServerRelativeUrl = folderPath };
return request;
}
private async Task CreateFolder(HttpClient client, string digest)
{
client.DefaultRequestHeaders.Add("X-RequestDigest", digest);
var request = CreateRequest("/test/foo");
string json = JsonConvert.SerializeObject(request);
StringContent strContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
strContent.Headers.ContentLength = json.Length;
HttpResponseMessage response = await client.PostAsync("_api/web/folders", strContent);
//response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
else
{
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.ReasonPhrase);
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
}
public async Task<string> GetDigest(HttpClient client)
{
string retVal = null;
string cmd = "_api/contextinfo";
HttpResponseMessage response = await client.PostAsJsonAsync(cmd, "");
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
JToken t = JToken.Parse(content);
retVal = t["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
}
return retVal;
}
}
}
但是这段代码总是失败,请求错误。
你能让"这个"代码工作并让我知道你是如何修复的吗?我在MSDN上发现了很多文章,但他们都使用了我不能使用的WebRequest的旧方法。我必须使用HttpClient。
编辑::
下面是从fiddler
捕获的原始请求POST http://bi.abhi.com/testweb/_api/web/folders HTTP/1.1
Accept: application/json; odata=verbose
X-RequestDigest: 0x8B2A0904D5056E49DB886A72D59A86264A000F9AB14CE728407ECCD6F4369A7AD2585967BE9A57085344A5ACC99A4DA61D59E5EFA9A54B9B83564B2EA736F7F4,21 Aug 2014 20:24:15 -0000
Content-Type: application/json; charset=utf-8
Host: bi.abhi.com
Content-Length: 67
Expect: 100-continue
{"__metadata":{"type":"SP.Folder"},"ServerRelativeUrl":"/test/foo"}
以下是fiddler
的原始响应HTTP/1.1 400 Bad Request
Cache-Control: private, max-age=0
Transfer-Encoding: chunked
Content-Type: application/json;odata=verbose;charset=utf-8
Expires: Wed, 06 Aug 2014 20:24:15 GMT
Last-Modified: Thu, 21 Aug 2014 20:24:15 GMT
Server: Microsoft-IIS/8.0
X-SharePointHealthScore: 0
SPClientServiceRequestDuration: 4
X-AspNet-Version: 4.0.30319
SPRequestGuid: a9c6b09c-9340-10e2-0000-093d0491623a
request-id: a9c6b09c-9340-10e2-0000-093d0491623a
X-RequestDigest: 0x8B2A0904D5056E49DB886A72D59A86264A000F9AB14CE728407ECCD6F4369A7AD2585967BE9A57085344A5ACC99A4DA61D59E5EFA9A54B9B83564B2EA736F7F4,21 Aug 2014 20:24:15 -0000
X-FRAME-OPTIONS: SAMEORIGIN
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 15.0.0.4569
X-Content-Type-Options: nosniff
X-MS-InvokeApp: 1; RequireReadOnly
Date: Thu, 21 Aug 2014 20:24:14 GMT
e6
{"error":{"code":"-1, System.InvalidOperationException","message":{"lang":"en-US","value":"The required version of WcfDataServices is missing. Please refer to http://go.microsoft.com/fwlink/?LinkId=321931 for more information."}}}
0
我已经完全修补了我的服务器环境,没有新的更新要应用。所以我不知道为什么它说所需的wcfdata服务缺失
我解决了这个问题。使用
上提供的答案http://social.msdn.microsoft.com/Forums/en-US/a58a4bec-e936-48f9-b881-bc0a7ebb7f8a/create-a-folder-in-sp2013-document-library-using-rest-using-http-client?forum=appsforsharepoint显然,当使用StringContent时,您必须将其设置为"application/json;odata=verbose",否则您将获得400个错误请求。StringContent设置Content-Type报头。
StringContent strContent = new StringContent(json);
strContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;odata=verbose");
完整的代码现在看起来像
class Program
{
static void Main(string[] args)
{
Program p = new Program();
int retVal = p.Process().Result;
}
private async Task<int> Process()
{
string url = "http://bi.abhi.com/testweb/";
using (HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }))
{
client.BaseAddress = new System.Uri(url);
client.DefaultRequestHeaders.Add("Accept", "application/json; odata=verbose");
string digest = await GetDigest(client);
Console.WriteLine("Digest " + digest);
try
{
await CreateFolder(client, digest);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
return 0;
}
private object CreateRequest(string folderPath)
{
var type = new { type = "SP.Folder" };
var request = new { __metadata = type, ServerRelativeUrl = folderPath };
return request;
}
private async Task CreateFolder(HttpClient client, string digest)
{
client.DefaultRequestHeaders.Add("X-RequestDigest", digest);
var request = CreateRequest("foo");
string json = JsonConvert.SerializeObject(request);
StringContent strContent = new StringContent(json);
strContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;odata=verbose");
HttpResponseMessage response = await client.PostAsync("_api/web/getfolderbyserverrelativeurl('test/test123/')/folders", strContent);
//response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
else
{
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.ReasonPhrase);
string content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
}
}
public async Task<string> GetDigest(HttpClient client)
{
string retVal = null;
string cmd = "_api/contextinfo";
HttpResponseMessage response = await client.PostAsJsonAsync(cmd, "");
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
JToken t = JToken.Parse(content);
retVal = t["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
}
return retVal;
}
}
如果这是SharePoint Online,这4个要求恐怕你做不到。您需要在请求中发送Authentication头或cookie。您可以添加SP客户端库,创建SharepointOnlineClientCredentials,使用方法
获取cookieSharePointOnlineCredentials.GetAuthenticationCookie
和添加cookie到httpclient的cookie容器。
如果你是在SP On premises,我认为它也不会工作,但你可以尝试将NetworkCredentials添加到httpclient请求:HttpClient。使用网络凭据GetAsync使用
选项UseDefaultCredentials = true
正如在已接受答案的注释中所说的那样。但是,我认为这行不通。