Skip to content

Instantly share code, notes, and snippets.

@BobGerman
Last active February 20, 2023 11:14
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save BobGerman/2f6bcbd3ca6bd75fd1ae175d53dba8cc to your computer and use it in GitHub Desktop.
Save BobGerman/2f6bcbd3ca6bd75fd1ae175d53dba8cc to your computer and use it in GitHub Desktop.
Sample code for calling SharePoint CSOM from an Azure Function
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.SharePoint.Client;
using System.Security.Cryptography.X509Certificates;
public static class csomHelper {
private static string ClientId = "<fill in app ID>";
private static string Cert = "myCert.pfx"; // Fill in name of your cert file and upload it
private static string CertPassword = "<fill in cert password>"; // TODO: Explore more secure place for this
private static string Authority = "https://login.windows.net/<tenant>.onmicrosoft.com/";
private static string Resource = "https://<tenant>.sharepoint.com/";
public async static Task<ClientContext> GetClientContext(string siteUrl)
{
var authenticationContext = new AuthenticationContext(Authority, false);
// TODO: Substitute your Azure function name for GetDocUrl2 below:
var certPath = Path.Combine(Environment.GetEnvironmentVariable("HOME"), "site\\wwwroot\\GetDocUrl2\\", Cert);
var cert = new X509Certificate2(System.IO.File.ReadAllBytes(certPath),
CertPassword,
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet);
var authenticationResult = await authenticationContext.AcquireTokenAsync(Resource, new ClientAssertionCertificate(ClientId, cert));
var token = authenticationResult.AccessToken;
var ctx = new ClientContext(siteUrl);
ctx.ExecutingWebRequest += (s, e) =>
{
e.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + authenticationResult.AccessToken;
};
return ctx;
}
}
{
"bindings": [
{
"authLevel": "function",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.IdentityModel.Clients.ActiveDirectory" : "3.13.7",
"Microsoft.SharePointOnline.CSOM": "16.1.5813.1200"
}
}
}
}
#load "csomHelper.csx"
using System.Net;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Utilities;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
ClientResult<string> result;
try {
log.Info("Executing function");
// Parse query parameters
string path = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "path", true) == 0)
.Value;
string siteUrl = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "siteUrl", true) == 0)
.Value;
// Get request body
dynamic data = await req.Content.ReadAsAsync<object>();
// Build item URL
string itemUrl = (siteUrl ?? data?.siteUrl).TrimEnd('/') + "/" + (path ?? data?.path).TrimStart('/');
string serverRelativeUrl = itemUrl.Substring(itemUrl.IndexOf('/',9));
// Get Office Online (WOPI) URL
using (var ctx = await csomHelper.GetClientContext(siteUrl))
{
File f = ctx.Web.GetFileByServerRelativeUrl (serverRelativeUrl);
result = f.ListItemAllFields.GetWOPIFrameUrl(SPWOPIFrameAction.View);
ctx.Load(f.ListItemAllFields);
ctx.ExecuteQuery();
}
// Return item URL or error
return itemUrl == null
? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a path on the query string or in the request body" + req.RequestUri)
: req.CreateResponse(HttpStatusCode.OK, result.Value);
}
catch (Exception ex)
{
string message = ex.Message + "\n" + ex.StackTrace;
return req.CreateResponse(HttpStatusCode.BadRequest, "ERROR: " + message);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment