Nicole
Nicole

Reputation: 1416

Retrieve all instances of recurring event via CSOM

I need to get all the instances of a recurring calendar event in Sharepoint 2013 online via CSOM. I read that it can't be done, that I need to do it via REST API directly.

My question:

1) Is it possible to get the items from a View instead of from a List, because the calendar comes with a default view where I can see all instances of the recurring event

2) I have an example of retrieveing data via REST un C# that's working fine, but I can't seem to add a Caml Query to it (in C#) here's my non-working code:

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();

I get 500 Internal server error

Any thoughts?? thank you

Upvotes: 1

Views: 1892

Answers (2)

Nicole
Nicole

Reputation: 1416

Thank you Vadim Gremyachev, your post got me on track.

I had 3 problems, the first one was calling "Items" instead of "getItems", and the second one was using "application/atom+xml;type=entry" as a ContentType (just as Vadim stated).

The third and last problem, was using simple quotes all over the query. Inside the ViewXml, I used scaped double quotes so they were not confused with the one closing the ViewXml element.

So, the working code ended up being like this:

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();

Upvotes: 0

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59318

I would recommend to utilize Fiddler to inspect REST SharePoint RESTfull web service requests.

In your case the endpoint is not correct. Since you need to request list items via CAML query, replace endpoint url from:

/_api/Web/lists/getbytitle('" + listName + "')/Items

to this one:

/_api/Web/lists/getbytitle('" + listName + "')/getitems

Secondly, application/atom+xml;type=entry HTTP Content-Type header is not supported in POST requests (see the list of supported MIME types below). So, replace the lines:

itemRequest.Accept = "application/atom+xml";
itemRequest.ContentType = "application/atom+xml;type=entry";

for example, with these ones:

itemRequest.Accept = "application/json";
itemRequest.ContentType = "application/json";

That's it.

The list of supported MIME types

  • application/json;odata=minimalmetadata;streaming=true
  • application/json;odata=minimalmetadata;streaming=false
  • application/json;odata=minimalmetadata
  • application/json;odata=fullmetadata;streaming=true
  • application/json;odata=fullmetadata;streaming=false
  • application/json;odata=fullmetadata
  • application/json;odata=nometadata;streaming=true
  • application/json;odata=nometadata;streaming=false
  • application/json;odata=nometadata
  • application/json;streaming=true
  • application/json;streaming=false
  • application/json;odata=verbose
  • application/json

You could also utilize the following class for performing REST requests:

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; }
}

Gist

Usage

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);

Upvotes: 1

Related Questions