Instantly share code, notes, and snippets.
Last active
September 24, 2020 17:56
Star
You must be signed in to star a gist
Generic Rest Client for SharePoint REST Inteface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Net; | |
using System.Net.Http; | |
using Newtonsoft.Json; | |
using Newtonsoft.Json.Linq; | |
namespace SharePoint.Client | |
{ | |
public class SharePointClient : WebClient | |
{ | |
static SharePointClient() | |
{ | |
Mapping[JsonFormatType.Verbose] = "application/json;odata=verbose"; | |
Mapping[JsonFormatType.MinimalMetadata] = "application/json; odata=minimalmetadata"; | |
Mapping[JsonFormatType.NoMetadata] = "application/json; odata=nometadata"; | |
} | |
public SharePointClient(string webUri) | |
{ | |
BaseAddress = webUri; | |
FormatType = JsonFormatType.Verbose; | |
if (Headers["X-FORMS_BASED_AUTH_ACCEPTED"] == null) | |
Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f"); | |
} | |
public JObject GetJson(string requestUri) | |
{ | |
return ExecuteJson(requestUri, HttpMethod.Get, null, default(string)); | |
} | |
public JObject ExecuteJson<T>(string requestUri, HttpMethod method, IDictionary<string, string> headers, T data) | |
{ | |
SetupRequest(method); | |
var payload = JsonConvert.SerializeObject(data); | |
var content = ExecuteJsonInner(requestUri, method, headers, payload); | |
return JObject.Parse(content); | |
} | |
public string ExecuteJsonInner(string requestUri, HttpMethod method, IDictionary<string, string> headers, string content) | |
{ | |
string result; | |
var uri = BaseAddress + requestUri; | |
if (headers != null) | |
{ | |
foreach (var key in headers.Keys) | |
{ | |
Headers.Add(key, headers[key]); | |
} | |
} | |
switch (method.Method) | |
{ | |
case "GET": | |
result = DownloadString(uri); | |
break; | |
case "POST": | |
result = (string.IsNullOrEmpty(content) ? UploadString(uri, method.Method) : UploadString(uri, method.Method, content)); | |
break; | |
default: | |
throw new NotSupportedException(string.Format("Method {0} is not supported", method.Method)); | |
} | |
return result; | |
} | |
private void SetupRequest(HttpMethod method) | |
{ | |
if (Headers[HttpRequestHeader.Accept] == null) | |
Headers.Add(HttpRequestHeader.ContentType, Mapping[FormatType]); | |
if (Headers[HttpRequestHeader.Accept] == null) | |
Headers.Add(HttpRequestHeader.Accept, Mapping[FormatType]); | |
if (method == HttpMethod.Post && Headers["X-RequestDigest"] == null) | |
{ | |
Headers.Add("X-RequestDigest", RequestFormDigest()); | |
} | |
} | |
public void UploadFileAsChunks(string address, string fileName, int chunkSize = 2048) | |
{ | |
var uriAddress = new Uri(address); | |
var fi = new FileInfo(fileName); | |
if(fi.Length <= chunkSize) | |
{ | |
this.UploadFile(address, fileName); | |
return; | |
} | |
SetupRequest(HttpMethod.Post); | |
var endpointUrl = string.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}')/savebinarystream", BaseAddress, uriAddress.LocalPath); | |
var fileContent = System.IO.File.ReadAllBytes(fileName); | |
var firstChunk = true; | |
var uploadId = Guid.NewGuid(); | |
var offset = 0L; | |
using (var inputStream = System.IO.File.OpenRead(fileName)) | |
{ | |
var buffer = new byte[chunkSize]; | |
int bytesRead; | |
while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0) | |
{ | |
if (firstChunk) | |
{ | |
endpointUrl = string.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}')/startupload(uploadId=guid'{2}')", BaseAddress, uriAddress.LocalPath, uploadId); | |
this.UploadData(endpointUrl, buffer); | |
firstChunk = false; | |
} | |
else if (inputStream.Position == inputStream.Length) | |
{ | |
endpointUrl = string.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}')/finishupload(uploadId=guid'{2}',fileOffset={3})", BaseAddress, uriAddress.LocalPath, uploadId, offset); | |
var finalBuffer = new byte[bytesRead]; | |
Array.Copy(buffer, finalBuffer, finalBuffer.Length); | |
this.UploadData(endpointUrl, finalBuffer); | |
} | |
else | |
{ | |
endpointUrl = string.Format("{0}/_api/web/getfilebyserverrelativeurl('{1}')/continueupload(uploadId=guid'{2}',fileOffset={3})", BaseAddress, uriAddress.LocalPath, uploadId, offset); | |
this.UploadData(endpointUrl, buffer); | |
} | |
offset += bytesRead; | |
} | |
} | |
} | |
public string RequestFormDigest() | |
{ | |
var content = ExecuteJsonInner("/_api/contextinfo", HttpMethod.Post, null, null); | |
var data = JObject.Parse(content); | |
return data["d"]["GetContextWebInformation"]["FormDigestValue"].ToString(); | |
} | |
public JsonFormatType FormatType { get; set; } | |
private static readonly Dictionary<JsonFormatType, string> Mapping = new Dictionary<JsonFormatType, string>(); | |
} | |
public enum JsonFormatType | |
{ | |
Verbose, | |
MinimalMetadata, | |
NoMetadata | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment