通过 CSOM 检索重复事件的所有实例
Retrieve all instances of recurring event via CSOM
我需要通过 CSOM 在线获取 Sharepoint 2013 中重复日历事件的所有实例。我读到它无法完成,我需要直接通过 REST API 来完成。
我的问题:
1) 是否可以从视图而不是列表中获取项目,因为日历带有默认视图,我可以在其中看到重复事件的所有实例
2) 我有一个通过 REST un C# 检索数据的示例,它工作正常,但我似乎无法向它添加 Caml 查询(在 C# 中)
这是我的非工作代码:
HttpWebRequest itemRequest =
(HttpWebRequest)HttpWebRequest.Create(sharepointUrl.ToString() + "/_api/Web/lists/getbytitle('" + listName + "')/Items");
itemRequest.Method = "POST";
itemRequest.Accept = "application/atom+xml";
itemRequest.ContentType = "application/atom+xml;type=entry";
itemRequest.Headers.Add("Authorization", "Bearer " + accessToken);
using (var writer = new StreamWriter(itemRequest.GetRequestStream()))
{
writer.Write(@"{ 'query' : {'__metadata': { 'type': 'SP.CamlQuery' }, 'ViewXml': '<View><Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>little test</Value></Eq></Where></Query></View>' } }");
}
HttpWebResponse itemResponse = (HttpWebResponse)itemRequest.GetResponse();
我收到 500 内部服务器错误
有什么想法吗??
谢谢
我建议使用 Fiddler 检查 REST SharePoint RESTfull Web 服务请求。
在您的情况下,端点不正确。由于您需要通过 CAML 查询请求列表项,因此将端点 url 替换为:
/_api/Web/lists/getbytitle('" + listName + "')/Items
给这个:
/_api/Web/lists/getbytitle('" + listName + "')/getitems
其次,application/atom+xml;type=entry
HTTP Content-Type
header 在 POST 请求中不受支持(请参阅下面支持的 MIME 类型列表)。因此,替换行:
itemRequest.Accept = "application/atom+xml";
itemRequest.ContentType = "application/atom+xml;type=entry";
例如,这些:
itemRequest.Accept = "application/json";
itemRequest.ContentType = "application/json";
就是这样。
支持的 MIME 类型列表
- application/json;odata=最小元数据;streaming=true
- application/json;odata=最小元数据;streaming=false
- application/json;odata=最小元数据
- application/json;odata=fullmetadata;streaming=true
- application/json;odata=fullmetadata;streaming=false
- application/json;odata=全元数据
- application/json;odata=nometadata;streaming=true
- application/json;odata=nometadata;streaming=false
- application/json;odata=nometadata
- application/json;流=真
- application/json;streaming=false
- application/json;odata=详细
- application/json
您还可以利用以下 class 来执行 REST 请求:
public class SPRestExecutor
{
public SPRestExecutor(Uri webUri,string accessToken)
{
WebUri = webUri;
AccessToken = accessToken;
}
public JObject ExecuteJsonWithDigest(string endpointUrl, HttpMethod method, IDictionary<string, string> headers, JObject payload)
{
var formDigestValue = RequestFormDigest();
var finalHeaders = new Dictionary<string, string>();
if (headers != null)
{
foreach (var key in headers.Keys)
{
finalHeaders.Add(key, headers[key]);
}
}
finalHeaders.Add("X-RequestDigest", formDigestValue);
var result = ExecuteJson(endpointUrl, method, finalHeaders, payload);
return result;
}
public JObject ExecuteJson(string endpointUrl, HttpMethod method, IDictionary<string, string> headers, JObject payload)
{
var request = (HttpWebRequest)WebRequest.Create(WebUri.ToString() + endpointUrl);
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + AccessToken);
request.Method = method.Method;
request.Accept = "application/json;odata=verbose";
request.ContentType = "application/json;odata=verbose";
if (payload != null)
{
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(payload);
writer.Flush();
}
}
using (var response = (HttpWebResponse)request.GetResponse())
{
using(var responseStream = response.GetResponseStream())
{
using (var reader = new StreamReader(responseStream))
{
var result = reader.ReadToEnd();
return JObject.Parse(result);
}
}
}
}
/// <summary>
/// Request Form Digest
/// </summary>
/// <returns></returns>
protected string RequestFormDigest()
{
var result = ExecuteJson("/_api/contextinfo", HttpMethod.Post, null, null);
return result["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
}
public string AccessToken { get; private set; }
public Uri WebUri { get; private set; }
}
用法
var client = new SPRestExecutor(webUri,accessToken);
var payload = JObject.Parse(@"{ 'query' : {'__metadata': { 'type': 'SP.CamlQuery' }, 'ViewXml': '<View><Query/></View>' } }");
var data = client.ExecuteJson("/_api/web/lists/getbytitle('Documents')/getitems", HttpMethod.Post, null, payload);
谢谢 Vadim Gremyachev,你的 post 让我走上正轨。
我有 3 个问题,第一个是调用 "Items" 而不是 "getItems",第二个是使用 "application/atom+xml;type=entry" 作为 ContentType(正如 Vadim 所说)。
第三个也是最后一个问题是在整个查询中使用简单的引号。在 ViewXml 中,我使用了转义双引号,这样它们就不会与关闭 ViewXml 元素的引号混淆。
所以,工作代码最终是这样的:
byte[] data = new ASCIIEncoding().GetBytes("{ 'query' : {'__metadata': { 'type': 'SP.CamlQuery' }, 'ViewXml': '<View><Query><Where><Eq><FieldRef Name=\"Title\"/><Value Type=\"Text\">little test</Value></Eq></Where></Query></View>' } }");
HttpWebRequest itemRequest =
(HttpWebRequest)HttpWebRequest.Create(sharepointUrl.ToString() + "/_api/Web/lists/getbytitle('" + listName + "')/getitems");
itemRequest.Method = "POST";
itemRequest.ContentType = "application/json; odata=verbose";
itemRequest.Accept = "application/atom+xml";
itemRequest.Headers.Add("Authorization", "Bearer " + accessToken);
itemRequest.ContentLength = data.Length;
Stream myStream = itemRequest.GetRequestStream();
myStream.Write(data, 0, data.Length);
myStream.Close();
HttpWebResponse itemResponse = (HttpWebResponse)itemRequest.GetResponse();
我需要通过 CSOM 在线获取 Sharepoint 2013 中重复日历事件的所有实例。我读到它无法完成,我需要直接通过 REST API 来完成。
我的问题:
1) 是否可以从视图而不是列表中获取项目,因为日历带有默认视图,我可以在其中看到重复事件的所有实例
2) 我有一个通过 REST un C# 检索数据的示例,它工作正常,但我似乎无法向它添加 Caml 查询(在 C# 中) 这是我的非工作代码:
HttpWebRequest itemRequest =
(HttpWebRequest)HttpWebRequest.Create(sharepointUrl.ToString() + "/_api/Web/lists/getbytitle('" + listName + "')/Items");
itemRequest.Method = "POST";
itemRequest.Accept = "application/atom+xml";
itemRequest.ContentType = "application/atom+xml;type=entry";
itemRequest.Headers.Add("Authorization", "Bearer " + accessToken);
using (var writer = new StreamWriter(itemRequest.GetRequestStream()))
{
writer.Write(@"{ 'query' : {'__metadata': { 'type': 'SP.CamlQuery' }, 'ViewXml': '<View><Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>little test</Value></Eq></Where></Query></View>' } }");
}
HttpWebResponse itemResponse = (HttpWebResponse)itemRequest.GetResponse();
我收到 500 内部服务器错误
有什么想法吗?? 谢谢
我建议使用 Fiddler 检查 REST SharePoint RESTfull Web 服务请求。
在您的情况下,端点不正确。由于您需要通过 CAML 查询请求列表项,因此将端点 url 替换为:
/_api/Web/lists/getbytitle('" + listName + "')/Items
给这个:
/_api/Web/lists/getbytitle('" + listName + "')/getitems
其次,application/atom+xml;type=entry
HTTP Content-Type
header 在 POST 请求中不受支持(请参阅下面支持的 MIME 类型列表)。因此,替换行:
itemRequest.Accept = "application/atom+xml";
itemRequest.ContentType = "application/atom+xml;type=entry";
例如,这些:
itemRequest.Accept = "application/json";
itemRequest.ContentType = "application/json";
就是这样。
支持的 MIME 类型列表
- application/json;odata=最小元数据;streaming=true
- application/json;odata=最小元数据;streaming=false
- application/json;odata=最小元数据
- application/json;odata=fullmetadata;streaming=true
- application/json;odata=fullmetadata;streaming=false
- application/json;odata=全元数据
- application/json;odata=nometadata;streaming=true
- application/json;odata=nometadata;streaming=false
- application/json;odata=nometadata
- application/json;流=真
- application/json;streaming=false
- application/json;odata=详细
- application/json
您还可以利用以下 class 来执行 REST 请求:
public class SPRestExecutor
{
public SPRestExecutor(Uri webUri,string accessToken)
{
WebUri = webUri;
AccessToken = accessToken;
}
public JObject ExecuteJsonWithDigest(string endpointUrl, HttpMethod method, IDictionary<string, string> headers, JObject payload)
{
var formDigestValue = RequestFormDigest();
var finalHeaders = new Dictionary<string, string>();
if (headers != null)
{
foreach (var key in headers.Keys)
{
finalHeaders.Add(key, headers[key]);
}
}
finalHeaders.Add("X-RequestDigest", formDigestValue);
var result = ExecuteJson(endpointUrl, method, finalHeaders, payload);
return result;
}
public JObject ExecuteJson(string endpointUrl, HttpMethod method, IDictionary<string, string> headers, JObject payload)
{
var request = (HttpWebRequest)WebRequest.Create(WebUri.ToString() + endpointUrl);
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + AccessToken);
request.Method = method.Method;
request.Accept = "application/json;odata=verbose";
request.ContentType = "application/json;odata=verbose";
if (payload != null)
{
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(payload);
writer.Flush();
}
}
using (var response = (HttpWebResponse)request.GetResponse())
{
using(var responseStream = response.GetResponseStream())
{
using (var reader = new StreamReader(responseStream))
{
var result = reader.ReadToEnd();
return JObject.Parse(result);
}
}
}
}
/// <summary>
/// Request Form Digest
/// </summary>
/// <returns></returns>
protected string RequestFormDigest()
{
var result = ExecuteJson("/_api/contextinfo", HttpMethod.Post, null, null);
return result["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
}
public string AccessToken { get; private set; }
public Uri WebUri { get; private set; }
}
用法
var client = new SPRestExecutor(webUri,accessToken);
var payload = JObject.Parse(@"{ 'query' : {'__metadata': { 'type': 'SP.CamlQuery' }, 'ViewXml': '<View><Query/></View>' } }");
var data = client.ExecuteJson("/_api/web/lists/getbytitle('Documents')/getitems", HttpMethod.Post, null, payload);
谢谢 Vadim Gremyachev,你的 post 让我走上正轨。
我有 3 个问题,第一个是调用 "Items" 而不是 "getItems",第二个是使用 "application/atom+xml;type=entry" 作为 ContentType(正如 Vadim 所说)。
第三个也是最后一个问题是在整个查询中使用简单的引号。在 ViewXml 中,我使用了转义双引号,这样它们就不会与关闭 ViewXml 元素的引号混淆。
所以,工作代码最终是这样的:
byte[] data = new ASCIIEncoding().GetBytes("{ 'query' : {'__metadata': { 'type': 'SP.CamlQuery' }, 'ViewXml': '<View><Query><Where><Eq><FieldRef Name=\"Title\"/><Value Type=\"Text\">little test</Value></Eq></Where></Query></View>' } }");
HttpWebRequest itemRequest =
(HttpWebRequest)HttpWebRequest.Create(sharepointUrl.ToString() + "/_api/Web/lists/getbytitle('" + listName + "')/getitems");
itemRequest.Method = "POST";
itemRequest.ContentType = "application/json; odata=verbose";
itemRequest.Accept = "application/atom+xml";
itemRequest.Headers.Add("Authorization", "Bearer " + accessToken);
itemRequest.ContentLength = data.Length;
Stream myStream = itemRequest.GetRequestStream();
myStream.Write(data, 0, data.Length);
myStream.Close();
HttpWebResponse itemResponse = (HttpWebResponse)itemRequest.GetResponse();