/// <summary> /// Returns the request digest from the current session/site /// </summary> /// <param name="context"></param> /// <returns></returns> public static async Task <string> GetRequestDigestAsync(this ClientContext context) { await new SynchronizationContextRemover(); //InitializeSecurity(context); using (var handler = new HttpClientHandler()) { string responseString = string.Empty; var accessToken = context.GetAccessToken(); context.Web.EnsureProperty(w => w.Url); using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = String.Format("{0}/_api/contextinfo", context.Web.Url); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } else { if (context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } } HttpResponseMessage response = await httpClient.SendAsync(request); if (response.IsSuccessStatusCode) { responseString = await response.Content.ReadAsStringAsync(); } else { var errorSb = new System.Text.StringBuilder(); errorSb.AppendLine(await response.Content.ReadAsStringAsync()); if (response.Headers.Contains("SPRequestGuid")) { var values = response.Headers.GetValues("SPRequestGuid"); if (values != null) { var spRequestGuid = values.FirstOrDefault(); errorSb.AppendLine($"ServerErrorTraceCorrelationId: {spRequestGuid}"); } } throw new Exception(errorSb.ToString()); } } var contextInformation = JsonSerializer.Deserialize <JsonElement>(responseString); string formDigestValue = contextInformation.GetProperty("d").GetProperty("GetContextWebInformation").GetProperty("FormDigestValue").GetString(); return(await Task.Run(() => formDigestValue).ConfigureAwait(false)); } }
/// <summary> /// Returns the request digest from the current session/site /// </summary> /// <param name="context"></param> /// <returns></returns> public static async Task <string> GetRequestDigest(this ClientContext context) { await new SynchronizationContextRemover(); //InitializeSecurity(context); using (var handler = new HttpClientHandler()) { string responseString = string.Empty; var accessToken = context.GetAccessToken(); context.Web.EnsureProperty(w => w.Url); if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = String.Format("{0}/_api/contextinfo", context.Web.Url); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } else { if (context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } } HttpResponseMessage response = await httpClient.SendAsync(request); if (response.IsSuccessStatusCode) { responseString = await response.Content.ReadAsStringAsync(); } else { throw new Exception(await response.Content.ReadAsStringAsync()); } } var contextInformation = JsonConvert.DeserializeObject <dynamic>(responseString); string formDigestValue = contextInformation.d.GetContextWebInformation.FormDigestValue; return(await Task.Run(() => formDigestValue)); } }
#pragma warning restore CA2000 private static async Task <AppMetadata> GetAppMetaData(AppCatalogScope scope, ClientContext context, string accessToken, PnPHttpProvider httpClient, string requestDigest, string id) { AppMetadata returnValue = null; int retryCount = 0; int waitTime = 10; // seconds var metadataRequestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/AvailableApps/GetById('{id}')"; using (var metadataRequest = new HttpRequestMessage(HttpMethod.Get, metadataRequestUrl)) { metadataRequest.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { metadataRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } if (!string.IsNullOrEmpty(requestDigest)) { metadataRequest.Headers.Add("X-RequestDigest", requestDigest); } while (returnValue == null && retryCount < 5) { // Perform actual post operation HttpResponseMessage metadataResponse = await httpClient.SendAsync(metadataRequest, new System.Threading.CancellationToken()); if (metadataResponse.IsSuccessStatusCode) { // If value empty, URL is taken var metadataResponseString = await metadataResponse.Content.ReadAsStringAsync(); if (metadataResponseString != null) { returnValue = JsonSerializer.Deserialize <AppMetadata>(metadataResponseString); } } else if (metadataResponse.StatusCode != HttpStatusCode.NotFound) { // Something went wrong... throw new Exception(await metadataResponse.Content.ReadAsStringAsync()); } if (returnValue == null) { // try again retryCount++; Thread.Sleep(waitTime * 1000); // wait 10 seconds } } return(returnValue); } }
public static async Task <bool> SetGroupImage(ClientContext context, byte[] file, string mimeType) { var accessToken = context.GetAccessToken(); var returnValue = false; using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{context.Web.Url}/_api/groupservice/setgroupimage"; var requestDigest = await context.GetRequestDigest(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } request.Headers.Add("X-RequestDigest", requestDigest); request.Headers.Add("binaryStringRequestBody", "true"); request.Content = new ByteArrayContent(file); request.Content.Headers.ContentType = new MediaTypeHeaderValue(mimeType); httpClient.Timeout = new TimeSpan(0, 0, 200); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); returnValue = response.IsSuccessStatusCode; } } return(await Task.Run(() => returnValue)); }
private async Task <bool> BaseRequest(Guid id, string method, bool appCatalog = false, Dictionary <string, object> postObject = null) { var context = _context; if (appCatalog == true) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); context = context.Clone(appcatalogUri); } var returnValue = false; var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{context.Web.Url}/_api/web/tenantappcatalog/AvailableApps/GetByID('{id}')/{method}"; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } request.Headers.Add("X-RequestDigest", await context.GetRequestDigest()); if (postObject != null) { var jsonBody = JsonConvert.SerializeObject(postObject); var requestBody = new StringContent(jsonBody); MediaTypeHeaderValue sharePointJsonMediaType; MediaTypeHeaderValue.TryParse("application/json;odata=nometadata;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; request.Content = requestBody; } // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { var responseJson = JObject.Parse(responseString); returnValue = true; } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } return(await Task.Run(() => returnValue)); }
/// <summary> /// Returns an available app /// </summary> /// <param name="id">The unique id of the app. Notice that this is not the product id as listed in the app catalog.</param> /// <returns></returns> private async Task <dynamic> BaseGetAvailableAsync(Guid id) { dynamic addins = null; var accessToken = _context.GetAccessToken(); using (var handler = new HttpClientHandler()) { _context.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(_context); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{_context.Web.Url}/_api/web/tenantappcatalog/AvailableApps"; if (Guid.Empty != id) { requestUrl = $"{_context.Web.Url}/_api/web/tenantappcatalog/AvailableApps/GetById('{id}')"; } HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } request.Headers.Add("X-RequestDigest", await _context.GetRequestDigest()); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { if (Guid.Empty == id) { var responseJson = JObject.Parse(responseString); var returnedAddins = responseJson["d"]["results"] as JArray; addins = JsonConvert.DeserializeObject <List <AppMetadata> >(returnedAddins.ToString()); } else { var responseJson = JObject.Parse(responseString); var returnedAddins = responseJson["d"]; addins = JsonConvert.DeserializeObject <AppMetadata>(returnedAddins.ToString()); } } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } return(await Task.Run(() => addins)); }
/// <summary> /// Creates a new Communication Site Collection /// </summary> /// <param name="clientContext">ClientContext object of a regular site</param> /// <param name="siteCollectionCreationInformation">information about the site to create</param> /// <returns>ClientContext object for the created site collection</returns> public static async Task <ClientContext> CreateAsync(ClientContext clientContext, CommunicationSiteCollectionCreationInformation siteCollectionCreationInformation) { await new SynchronizationContextRemover(); ClientContext responseContext = null; var accessToken = clientContext.GetAccessToken(); using (var handler = new HttpClientHandler()) { clientContext.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(clientContext); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{clientContext.Web.Url}/_api/SPSiteManager/Create"; // string requestUrl = String.Format("{0}/_api/sitepages/communicationsite/create", clientContext.Web.Url); var siteDesignId = GetSiteDesignId(siteCollectionCreationInformation); Dictionary <string, object> payload = new Dictionary <string, object>(); payload.Add("__metadata", new { type = "Microsoft.SharePoint.Portal.SPSiteCreationRequest" }); payload.Add("Title", siteCollectionCreationInformation.Title); payload.Add("Lcid", siteCollectionCreationInformation.Lcid); payload.Add("ShareByEmailEnabled", siteCollectionCreationInformation.ShareByEmailEnabled); payload.Add("Url", siteCollectionCreationInformation.Url); // Deprecated // payload.Add("AllowFileSharingForGuestUsers", siteCollectionCreationInformation.AllowFileSharingForGuestUsers); if (siteDesignId != Guid.Empty) { payload.Add("SiteDesignId", siteDesignId); } payload.Add("Classification", siteCollectionCreationInformation.Classification == null ? "" : siteCollectionCreationInformation.Classification); payload.Add("Description", siteCollectionCreationInformation.Description == null ? "" : siteCollectionCreationInformation.Description); payload.Add("WebTemplate", "SITEPAGEPUBLISHING#0"); payload.Add("WebTemplateExtensionId", Guid.Empty); var body = new { request = payload }; // Serialize request object to JSON var jsonBody = JsonConvert.SerializeObject(body); var requestBody = new StringContent(jsonBody); // Build Http request HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Content = requestBody; request.Headers.Add("accept", "application/json;odata=verbose"); MediaTypeHeaderValue sharePointJsonMediaType = null; MediaTypeHeaderValue.TryParse("application/json;odata=verbose;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } requestBody.Headers.Add("X-RequestDigest", await clientContext.GetRequestDigest()); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { var responseJson = JObject.Parse(responseString); #if !NETSTANDARD2_0 if (Convert.ToInt32(responseJson["d"]["Create"]["SiteStatus"]) == 2) #else if (responseJson["d"]["Create"]["SiteStatus"].Value <int>() == 2) #endif { responseContext = clientContext.Clone(responseJson["d"]["Create"]["SiteUrl"].ToString()); } else { throw new Exception(responseString); } } catch (Exception) { throw; } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } return(await Task.Run(() => responseContext)); } }
/// <summary> /// Groupifies a classic team site by creating a group for it and connecting the site with the newly created group /// </summary> /// <param name="clientContext">ClientContext object of a regular site</param> /// <param name="siteCollectionGroupifyInformation">information about the site to create</param> /// <returns>ClientContext object for the created site collection</returns> public static async Task <ClientContext> GroupifyAsync(ClientContext clientContext, TeamSiteCollectionGroupifyInformation siteCollectionGroupifyInformation) { if (siteCollectionGroupifyInformation == null) { throw new ArgumentException("Missing value for siteCollectionGroupifyInformation", "sitecollectionGroupifyInformation"); } if (!string.IsNullOrEmpty(siteCollectionGroupifyInformation.Alias) && siteCollectionGroupifyInformation.Alias.Contains(" ")) { throw new ArgumentException("Alias cannot contain spaces", "Alias"); } if (string.IsNullOrEmpty(siteCollectionGroupifyInformation.DisplayName)) { throw new ArgumentException("DisplayName is required", "DisplayName"); } await new SynchronizationContextRemover(); ClientContext responseContext = null; var accessToken = clientContext.GetAccessToken(); if (clientContext.IsAppOnly()) { throw new Exception("App-Only is currently not supported."); } using (var handler = new HttpClientHandler()) { clientContext.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(clientContext); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = String.Format("{0}/_api/GroupSiteManager/CreateGroupForSite", clientContext.Web.Url); Dictionary <string, object> payload = new Dictionary <string, object>(); payload.Add("displayName", siteCollectionGroupifyInformation.DisplayName); payload.Add("alias", siteCollectionGroupifyInformation.Alias); payload.Add("isPublic", siteCollectionGroupifyInformation.IsPublic); var optionalParams = new Dictionary <string, object>(); optionalParams.Add("Description", siteCollectionGroupifyInformation.Description != null ? siteCollectionGroupifyInformation.Description : ""); // Handle groupify options var creationOptionsValues = new List <string>(); if (siteCollectionGroupifyInformation.KeepOldHomePage) { creationOptionsValues.Add("SharePointKeepOldHomepage"); } var creationOptions = new Dictionary <string, object>(); creationOptions.Add("results", creationOptionsValues.ToArray()); optionalParams.Add("CreationOptions", creationOptions); optionalParams.Add("Classification", siteCollectionGroupifyInformation.Classification != null ? siteCollectionGroupifyInformation.Classification : ""); payload.Add("optionalParams", optionalParams); var body = payload; // Serialize request object to JSON var jsonBody = JsonConvert.SerializeObject(body); var requestBody = new StringContent(jsonBody); // Build Http request HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Content = requestBody; request.Headers.Add("accept", "application/json;odata=verbose"); MediaTypeHeaderValue sharePointJsonMediaType = null; MediaTypeHeaderValue.TryParse("application/json;odata=verbose;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } requestBody.Headers.Add("X-RequestDigest", await clientContext.GetRequestDigest()); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); var responseJson = JObject.Parse(responseString); // SiteStatus 1 = Provisioning, SiteStatus 2 = Ready if (Convert.ToInt32(responseJson["d"]["CreateGroupForSite"]["SiteStatus"]) == 2 || Convert.ToInt32(responseJson["d"]["CreateGroupForSite"]["SiteStatus"]) == 1) { responseContext = clientContext; } else { throw new Exception(responseString); } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } return(await Task.Run(() => responseContext)); } }
protected override void ExecuteCmdlet() { if (Url.StartsWith("/")) { // prefix the url with the current web url Url = UrlUtility.Combine(ClientContext.Url, Url); } var accessToken = this.ClientContext.GetAccessToken(); var method = new HttpMethod(Method.ToString()); using (var handler = new HttpClientHandler()) { // we're not in app-only or user + app context, so let's fall back to cookie based auth if (string.IsNullOrEmpty(accessToken)) { SetAuthenticationCookies(handler, ClientContext); } using (var httpClient = new PnPHttpProvider(handler)) { var requestUrl = Url; HttpRequestMessage request = new HttpRequestMessage(method, requestUrl); request.Headers.Add("accept", "application/json;odata=nometadata"); if (Method == HttpRequestMethod.Merge) { method = HttpMethod.Post; request.Headers.Add("X-HTTP-Method", "MERGE"); } if (Method == HttpRequestMethod.Merge || Method == HttpRequestMethod.Delete) { request.Headers.Add("IF-MATCH", "*"); } if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } else { if (ClientContext.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } } request.Headers.Add("X-RequestDigest", ClientContext.GetRequestDigestAsync().GetAwaiter().GetResult()); if (Method == HttpRequestMethod.Post) { if (string.IsNullOrEmpty(ContentType)) { ContentType = "application/json"; } var contentString = Content is string?Content.ToString() : JsonSerializer.Serialize(Content); request.Content = new StringContent(contentString, System.Text.Encoding.UTF8); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(ContentType); } HttpResponseMessage response = httpClient.SendAsync(request, new System.Threading.CancellationToken()).Result; if (response.IsSuccessStatusCode) { var responseString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); if (responseString != null) { WriteObject(JsonSerializer.Deserialize <Hashtable>(responseString)); } } else { // Something went wrong... throw new Exception(response.Content.ReadAsStringAsync().GetAwaiter().GetResult()); } } } }
/// <summary> /// Returns an available app /// </summary> /// <param name="id">The unique id of the app. Notice that this is not the product id as listed in the app catalog.</param> /// <param name="title">The title of the app.</param> /// <param name="scope">Specifies the app catalog to work with. Defaults to Tenant</param> /// <returns></returns> private async Task <dynamic> BaseGetAvailableAsync(AppCatalogScope scope, Guid id = default(Guid), string title = "") { dynamic addins = null; var accessToken = _context.GetAccessToken(); using (var handler = new HttpClientHandler()) { if (string.IsNullOrEmpty(accessToken)) { _context.SetAuthenticationCookiesForHandler(handler); } _context.Web.EnsureProperty(w => w.Url); using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{_context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/AvailableApps"; if (Guid.Empty != id) { requestUrl = $"{_context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/AvailableApps/GetById('{id}')"; } using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl)) { request.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Add("X-RequestDigest", await _context.GetRequestDigestAsync().ConfigureAwait(false)); } else { if (_context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } request.Headers.Add("X-RequestDigest", await _context.GetRequestDigestAsync(handler.CookieContainer).ConfigureAwait(false)); } // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { if (Guid.Empty == id && string.IsNullOrEmpty(title)) { var resultCollection = JsonSerializer.Deserialize <ResultCollection <AppMetadata> >(responseString, new JsonSerializerOptions() { IgnoreNullValues = true }); if (resultCollection.Items != null && resultCollection.Items.Any()) { addins = resultCollection.Items; } } else if (!String.IsNullOrEmpty(title)) { var resultCollection = JsonSerializer.Deserialize <ResultCollection <AppMetadata> >(responseString, new JsonSerializerOptions() { IgnoreNullValues = true }); if (resultCollection.Items != null && resultCollection.Items.Any()) { addins = resultCollection.Items.FirstOrDefault(a => a.Title.Equals(title)); } } else { addins = JsonSerializer.Deserialize <AppMetadata>(responseString); } } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } } return(await Task.Run(() => addins)); }
/// <summary> /// Creates a new Modern Team Site Collection /// </summary> /// <param name="clientContext">ClientContext object of a regular site</param> /// <param name="siteCollectionCreationInformation">information about the site to create</param> /// <param name="delayAfterCreation">Defines the number of seconds to wait after creation</param> /// <returns>ClientContext object for the created site collection</returns> public static async Task <ClientContext> CreateAsync(ClientContext clientContext, TeamSiteCollectionCreationInformation siteCollectionCreationInformation, Int32 delayAfterCreation = 0) { if (siteCollectionCreationInformation.Alias.Contains(" ")) { throw new ArgumentException("Alias cannot contain spaces", "Alias"); } await new SynchronizationContextRemover(); ClientContext responseContext = null; if (clientContext.IsAppOnly()) { throw new Exception("App-Only is currently not supported."); } var accessToken = clientContext.GetAccessToken(); using (var handler = new HttpClientHandler()) { clientContext.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(clientContext); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = String.Format("{0}/_api/GroupSiteManager/CreateGroupEx", clientContext.Web.Url); Dictionary <string, object> payload = new Dictionary <string, object>(); payload.Add("displayName", siteCollectionCreationInformation.DisplayName); payload.Add("alias", siteCollectionCreationInformation.Alias); payload.Add("isPublic", siteCollectionCreationInformation.IsPublic); var optionalParams = new Dictionary <string, object>(); optionalParams.Add("Description", siteCollectionCreationInformation.Description ?? ""); optionalParams.Add("Classification", siteCollectionCreationInformation.Classification ?? ""); var creationOptionsValues = new List <string>(); if (siteCollectionCreationInformation.Lcid != 0) { creationOptionsValues.Add($"SPSiteLanguage:{siteCollectionCreationInformation.Lcid}"); } creationOptionsValues.Add($"HubSiteId:{siteCollectionCreationInformation.HubSiteId}"); optionalParams.Add("CreationOptions", creationOptionsValues); if (siteCollectionCreationInformation.Owners != null && siteCollectionCreationInformation.Owners.Length > 0) { optionalParams.Add("Owners", siteCollectionCreationInformation.Owners); } payload.Add("optionalParams", optionalParams); var body = payload; // Serialize request object to JSON var jsonBody = JsonConvert.SerializeObject(body); var requestBody = new StringContent(jsonBody); // Build Http request HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Content = requestBody; request.Headers.Add("accept", "application/json;odata.metadata=none"); request.Headers.Add("odata-version", "4.0"); MediaTypeHeaderValue sharePointJsonMediaType = null; MediaTypeHeaderValue.TryParse("application/json;odata.metadata=none;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } requestBody.Headers.Add("X-RequestDigest", await clientContext.GetRequestDigest()); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); var responseJson = JObject.Parse(responseString); #if !NETSTANDARD2_0 if (Convert.ToInt32(responseJson["SiteStatus"]) == 2) #else if (responseJson["SiteStatus"].Value <int>() == 2) #endif { responseContext = clientContext.Clone(responseJson["SiteUrl"].ToString()); } else { throw new Exception(responseString); } // If there is a delay, let's wait if (delayAfterCreation > 0) { System.Threading.Thread.Sleep(TimeSpan.FromSeconds(delayAfterCreation)); } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } return(await Task.Run(() => responseContext)); } }
/// <summary> /// Creates a new Modern Team Site Collection /// </summary> /// <param name="clientContext">ClientContext object of a regular site</param> /// <param name="siteCollectionCreationInformation">information about the site to create</param> /// <param name="delayAfterCreation">Defines the number of seconds to wait after creation</param> /// <param name="maxRetryCount">Maximum number of retries for a pending site provisioning. Default 12 retries.</param> /// <param name="retryDelay">Delay between retries for a pending site provisioning. Default 10 seconds.</param> /// <returns>ClientContext object for the created site collection</returns> public static async Task <ClientContext> CreateAsync(ClientContext clientContext, TeamSiteCollectionCreationInformation siteCollectionCreationInformation, Int32 delayAfterCreation = 0, Int32 maxRetryCount = 12, // Maximum number of retries (12 x 10 sec = 120 sec = 2 mins) Int32 retryDelay = 1000 * 10 // Wait time default to 10sec ) { if (siteCollectionCreationInformation.Alias.Contains(" ")) { throw new ArgumentException("Alias cannot contain spaces", "Alias"); } await new SynchronizationContextRemover(); ClientContext responseContext = null; if (clientContext.IsAppOnly()) { throw new Exception("App-Only is currently not supported."); } var accessToken = clientContext.GetAccessToken(); using (var handler = new HttpClientHandler()) { clientContext.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(clientContext); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = String.Format("{0}/_api/GroupSiteManager/CreateGroupEx", clientContext.Web.Url); Dictionary <string, object> payload = new Dictionary <string, object>(); payload.Add("displayName", siteCollectionCreationInformation.DisplayName); payload.Add("alias", siteCollectionCreationInformation.Alias); payload.Add("isPublic", siteCollectionCreationInformation.IsPublic); var optionalParams = new Dictionary <string, object>(); optionalParams.Add("Description", siteCollectionCreationInformation.Description ?? ""); optionalParams.Add("Classification", siteCollectionCreationInformation.Classification ?? ""); var creationOptionsValues = new List <string>(); if (siteCollectionCreationInformation.Lcid != 0) { creationOptionsValues.Add($"SPSiteLanguage:{siteCollectionCreationInformation.Lcid}"); } creationOptionsValues.Add($"HubSiteId:{siteCollectionCreationInformation.HubSiteId}"); optionalParams.Add("CreationOptions", creationOptionsValues); if (siteCollectionCreationInformation.Owners != null && siteCollectionCreationInformation.Owners.Length > 0) { optionalParams.Add("Owners", siteCollectionCreationInformation.Owners); } payload.Add("optionalParams", optionalParams); var body = payload; // Serialize request object to JSON var jsonBody = JsonConvert.SerializeObject(body); var requestBody = new StringContent(jsonBody); // Build Http request HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Content = requestBody; request.Headers.Add("accept", "application/json;odata.metadata=none"); request.Headers.Add("odata-version", "4.0"); MediaTypeHeaderValue sharePointJsonMediaType = null; MediaTypeHeaderValue.TryParse("application/json;odata.metadata=none;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } requestBody.Headers.Add("X-RequestDigest", await clientContext.GetRequestDigest()); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); var responseJson = JObject.Parse(responseString); #if !NETSTANDARD2_0 if (Convert.ToInt32(responseJson["SiteStatus"]) == 2) #else if (responseJson["SiteStatus"].Value <int>() == 2) #endif { responseContext = clientContext.Clone(responseJson["SiteUrl"].ToString()); } else { /* * BEGIN : Changes to address the SiteStatus=Provisioning scenario */ if (Convert.ToInt32(responseJson["SiteStatus"]) == 1 && string.IsNullOrWhiteSpace(Convert.ToString(responseJson["ErrorMessage"]))) { var spOperationsMaxRetryCount = maxRetryCount; var spOperationsRetryWait = retryDelay; var siteCreated = false; var siteUrl = string.Empty; var retryAttempt = 1; do { if (retryAttempt > 1) { System.Threading.Thread.Sleep(retryAttempt * spOperationsRetryWait); } try { var groupId = responseJson["GroupId"].ToString(); var siteStatusRequestUrl = $"{clientContext.Web.Url}/_api/groupsitemanager/GetSiteStatus('{groupId}')"; var siteStatusRequest = new HttpRequestMessage(HttpMethod.Get, siteStatusRequestUrl); siteStatusRequest.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { siteStatusRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } siteStatusRequest.Headers.Add("X-RequestDigest", await clientContext.GetRequestDigest()); var siteStatusResponse = await httpClient.SendAsync(siteStatusRequest, new System.Threading.CancellationToken()); var siteStatusResponseString = await siteStatusResponse.Content.ReadAsStringAsync(); var siteStatusResponseJson = JObject.Parse(siteStatusResponseString); if (siteStatusResponse.IsSuccessStatusCode) { var siteStatus = Convert.ToInt32(siteStatusResponseJson["d"]["GetSiteStatus"]["SiteStatus"].ToString()); if (siteStatus == 2) { siteCreated = true; siteUrl = siteStatusResponseJson["d"]["GetSiteStatus"]["SiteUrl"].ToString(); } } } catch (Exception) { // Just skip it and retry after a delay } retryAttempt++; }while (!siteCreated && retryAttempt <= spOperationsMaxRetryCount); if (siteCreated) { responseContext = clientContext.Clone(siteUrl); } else { throw new Exception("OfficeDevPnP.Core.Sites.SiteCollection.CreateAsync: Could not create team site."); } } else { throw new Exception(responseString); } /* * END : Changes to address the SiteStatus=Provisioning scenario */ } // If there is a delay, let's wait if (delayAfterCreation > 0) { System.Threading.Thread.Sleep(TimeSpan.FromSeconds(delayAfterCreation)); } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } return(await Task.Run(() => responseContext)); } }
private static async Task <ClientContext> CreateAsync(ClientContext clientContext, string owner, Dictionary <string, object> payload, Int32 delayAfterCreation = 0, Int32 maxRetryCount = 12, // Maximum number of retries (12 x 10 sec = 120 sec = 2 mins) Int32 retryDelay = 1000 * 10 // Wait time default to 10sec ) { await new SynchronizationContextRemover(); ClientContext responseContext = null; if (clientContext.IsAppOnly() && string.IsNullOrEmpty(owner)) { throw new Exception("You need to set the owner in App-only context"); } var accessToken = clientContext.GetAccessToken(); using (var handler = new HttpClientHandler()) { clientContext.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(clientContext); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{clientContext.Web.Url}/_api/SPSiteManager/Create"; var body = new { request = payload }; // Serialize request object to JSON var jsonBody = JsonConvert.SerializeObject(body); var requestBody = new StringContent(jsonBody); // Build Http request HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Content = requestBody; request.Headers.Add("accept", "application/json;odata.metadata=none"); request.Headers.Add("odata-version", "4.0"); MediaTypeHeaderValue sharePointJsonMediaType = null; MediaTypeHeaderValue.TryParse("application/json;odata.metadata=none;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } requestBody.Headers.Add("X-RequestDigest", await clientContext.GetRequestDigest()); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { var responseJson = JObject.Parse(responseString); #if !NETSTANDARD2_0 if (Convert.ToInt32(responseJson["SiteStatus"]) == 2) #else if (responseJson["SiteStatus"].Value <int>() == 2) #endif { responseContext = clientContext.Clone(responseJson["SiteUrl"].ToString()); } else { /* * BEGIN : Changes to address the SiteStatus=Provisioning scenario */ if (Convert.ToInt32(responseJson["SiteStatus"]) == 1) { var spOperationsMaxRetryCount = maxRetryCount; var spOperationsRetryWait = retryDelay; var siteCreated = false; var siteUrl = string.Empty; var retryAttempt = 1; do { if (retryAttempt > 1) { System.Threading.Thread.Sleep(retryAttempt * spOperationsRetryWait); } try { var urlToCheck = HttpUtility.UrlEncode(payload["Url"].ToString()); var siteStatusRequestUrl = $"{clientContext.Web.Url}/_api/SPSiteManager/status?url='{urlToCheck}'"; var siteStatusRequest = new HttpRequestMessage(HttpMethod.Get, siteStatusRequestUrl); siteStatusRequest.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { siteStatusRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } siteStatusRequest.Headers.Add("X-RequestDigest", await clientContext.GetRequestDigest()); var siteStatusResponse = await httpClient.SendAsync(siteStatusRequest, new System.Threading.CancellationToken()); var siteStatusResponseString = await siteStatusResponse.Content.ReadAsStringAsync(); var siteStatusResponseJson = JObject.Parse(siteStatusResponseString); if (siteStatusResponse.IsSuccessStatusCode) { var siteStatus = Convert.ToInt32(siteStatusResponseJson["d"]["Status"]["SiteStatus"].ToString()); if (siteStatus == 2) { siteCreated = true; siteUrl = siteStatusResponseJson["d"]["Status"]["SiteUrl"].ToString(); } } } catch (Exception) { // Just skip it and retry after a delay } retryAttempt++; }while (!siteCreated && retryAttempt <= spOperationsMaxRetryCount); if (siteCreated) { responseContext = clientContext.Clone(siteUrl); } else { throw new Exception($"OfficeDevPnP.Core.Sites.SiteCollection.CreateAsync: Could not create {payload["WebTemplate"].ToString()} site."); } } else { throw new Exception(responseString); } /* * END : Changes to address the SiteStatus=Provisioning scenario */ } } catch (Exception) { throw; } } // If there is a delay, let's wait if (delayAfterCreation > 0) { System.Threading.Thread.Sleep(TimeSpan.FromSeconds(delayAfterCreation)); } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } return(await Task.Run(() => responseContext)); } }
/// <summary> /// Internal private method to process an HTTP request toward the ThemeManager REST APIs /// </summary> /// <param name="context">The current ClientContext of CSOM</param> /// <param name="action">The action to perform</param> /// <param name="postObject">The body of the request</param> /// <param name="accessToken">An optional Access Token for OAuth authorization</param> /// <returns>A boolean declaring whether the operation was successful</returns> private static async Task <bool> BaseRequest(ClientContext context, ThemeAction action, Object postObject, String accessToken = null) { var result = false; // If we don't have the access token if (String.IsNullOrEmpty(accessToken)) { // Try to get one from the current context accessToken = context.GetAccessToken(); } using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); // We're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { // Reference here: https://docs.microsoft.com/en-us/sharepoint/dev/declarative-customization/site-theming/sharepoint-site-theming-rest-api string requestUrl = $"{context.Web.Url}/_api/thememanager/{action.ToString()}"; // Always make a POST request HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("ACCEPT", "application/json; odata.metadata=minimal"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } request.Headers.Add("X-RequestDigest", await context.GetRequestDigestAsync()); request.Headers.Add("ODATA-VERSION", "4.0"); if (postObject != null) { var jsonBody = JsonConvert.SerializeObject(postObject); var requestBody = new StringContent(jsonBody); MediaTypeHeaderValue sharePointJsonMediaType; MediaTypeHeaderValue.TryParse("application/json;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; request.Content = requestBody; } // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { var responseJson = JObject.Parse(responseString); result = true; } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } return(await Task.Run(() => result)); }
#pragma warning disable CA2000 private async Task <AppMetadata> BaseAddRequest(byte[] file, string filename, bool overwrite, int timeoutSeconds, AppCatalogScope scope) { AppMetadata returnValue = null; var isCloned = false; var context = _context; if (scope == AppCatalogScope.Tenant) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); context = context.Clone(appcatalogUri); isCloned = true; } var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); if (string.IsNullOrEmpty(accessToken)) { context.SetAuthenticationCookiesForHandler(handler); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/Add(overwrite={(overwrite.ToString().ToLower())}, url='{filename}')"; var requestDigest = string.Empty; if (!string.IsNullOrEmpty(accessToken)) { requestDigest = await context.GetRequestDigestAsync().ConfigureAwait(false); } else { requestDigest = await context.GetRequestDigestAsync(handler.CookieContainer).ConfigureAwait(false); } using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl)) { request.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } else { if (context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } } if (!string.IsNullOrEmpty(requestDigest)) { request.Headers.Add("X-RequestDigest", requestDigest); } request.Headers.Add("binaryStringRequestBody", "true"); request.Content = new ByteArrayContent(file); httpClient.Timeout = new TimeSpan(0, 0, timeoutSeconds); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { using (var jsonDocument = JsonDocument.Parse(responseString)) { if (jsonDocument.RootElement.TryGetProperty("UniqueId", out JsonElement uniqueIdElement)) { var id = uniqueIdElement.GetString(); returnValue = await GetAppMetaData(scope, context, accessToken, httpClient, requestDigest, id); } } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } } if (isCloned) { context.Dispose(); } return(await Task.Run(() => returnValue)); }
#pragma warning restore CA2000 private async Task <bool> SyncToTeamsImplementation(Guid appId) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); using (var context = _context.Clone(appcatalogUri)) { var returnValue = false; var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); if (string.IsNullOrEmpty(accessToken)) { context.SetAuthenticationCookiesForHandler(handler); } // find the app by id var list = context.Web.GetListByUrl("appcatalog"); var query = new CamlQuery { ViewXml = $"<View><Query><Where><Contains><FieldRef Name='UniqueId'/><Value Type='Text'>{appId}</Value></Contains></Where></Query></View>" }; var items = list.GetItems(query); context.Load(items); context.ExecuteQueryRetry(); if (items.Count > 0) { using (var httpClient = new PnPHttpProvider(handler)) { var requestUrl = $"{context.Web.Url}/_api/web/tenantappcatalog/SyncSolutionToTeams(id={items[0].Id})"; using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl)) { request.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Add("X-RequestDigest", await context.GetRequestDigestAsync().ConfigureAwait(false)); } else { if (context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } request.Headers.Add("X-RequestDigest", await context.GetRequestDigestAsync(handler.CookieContainer).ConfigureAwait(false)); } // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { returnValue = true; } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } } } return(await Task.Run(() => returnValue)); } }
#pragma warning disable CA2000 private async Task <bool> BaseRequest(Guid id, AppManagerAction action, bool switchToAppCatalogContext, Dictionary <string, object> postObject, AppCatalogScope scope, int timeoutSeconds = 200) { var isCloned = false; var context = _context; if (switchToAppCatalogContext == true && scope == AppCatalogScope.Tenant) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); context = context.Clone(appcatalogUri); isCloned = true; } var returnValue = false; var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); if (string.IsNullOrEmpty(accessToken)) { context.SetAuthenticationCookiesForHandler(handler); } using (var httpClient = new PnPHttpProvider(handler)) { httpClient.Timeout = new TimeSpan(0, 0, timeoutSeconds); var method = action.ToString(); var requestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/AvailableApps/GetByID('{id}')/{method}"; using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl)) { request.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Add("X-RequestDigest", await context.GetRequestDigestAsync().ConfigureAwait(false)); } else { if (context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } request.Headers.Add("X-RequestDigest", await context.GetRequestDigestAsync(handler.CookieContainer).ConfigureAwait(false)); } if (postObject != null) { var jsonBody = JsonSerializer.Serialize(postObject); var requestBody = new StringContent(jsonBody); if (MediaTypeHeaderValue.TryParse("application/json;odata=nometadata;charset=utf-8", out MediaTypeHeaderValue sharePointJsonMediaType)) { requestBody.Headers.ContentType = sharePointJsonMediaType; } request.Content = requestBody; } // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { returnValue = true; } catch { } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } } if (isCloned) { context.Dispose(); } return(await Task.Run(() => returnValue)); }
private async Task <AppMetadata> BaseAddRequest(byte[] file, string filename, bool overwrite = false, bool appCatalog = true) { AppMetadata returnValue = null; var context = _context; if (appCatalog == true) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); context = context.Clone(appcatalogUri); } var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{context.Web.Url}/_api/web/tenantappcatalog/Add(overwrite={(overwrite.ToString().ToLower())}, url='{filename}')"; var requestDigest = await context.GetRequestDigest(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } request.Headers.Add("X-RequestDigest", requestDigest); request.Headers.Add("binaryStringRequestBody", "true"); request.Content = new ByteArrayContent(file); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { var responseJson = JObject.Parse(responseString); var id = responseJson["d"]["UniqueId"].ToString(); var metadataRequestUrl = $"{context.Web.Url}/_api/web/tenantappcatalog/AvailableApps/GetById('{id}')"; HttpRequestMessage metadataRequest = new HttpRequestMessage(HttpMethod.Post, metadataRequestUrl); metadataRequest.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { metadataRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } metadataRequest.Headers.Add("X-RequestDigest", requestDigest); // Perform actual post operation HttpResponseMessage metadataResponse = await httpClient.SendAsync(metadataRequest, new System.Threading.CancellationToken()); if (metadataResponse.IsSuccessStatusCode) { // If value empty, URL is taken var metadataResponseString = await metadataResponse.Content.ReadAsStringAsync(); if (metadataResponseString != null) { var metadataResponseJson = JObject.Parse(metadataResponseString); var returnedAddins = metadataResponseJson["d"]; returnValue = JsonConvert.DeserializeObject <AppMetadata>(returnedAddins.ToString()); } } else { // Something went wrong... throw new Exception(await metadataResponse.Content.ReadAsStringAsync()); } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } return(await Task.Run(() => returnValue)); }
/// <summary> /// Requests the request digest from the current session/site /// </summary> /// <param name="context">The current ClientContext with Site-Collection-Admin-Level credentials.</param> /// <returns>The Request Digest as string.</returns> private async Task <string> BaseGetRequestDigest(ClientContext context) { //await new SynchronizationContextRemover(); JObject requestDigest = null; string requestDigestString = null; using (var handler = new HttpClientHandler()) { var accessToken = context.GetAccessToken(); context.Web.EnsureProperty(w => w.Url); if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = String.Format("{0}/_api/contextinfo", context.Web.Url); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } else { if (context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } } HttpResponseMessage response = await httpClient.SendAsync(request); if (response.IsSuccessStatusCode) { var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { try { var resultCollection = Newtonsoft.Json.JsonConvert.DeserializeObject(responseString); requestDigest = resultCollection as JObject; requestDigestString = requestDigest?.First.First.First.First.Value <string>("FormDigestValue"); } catch { } } } else { var errorSb = new System.Text.StringBuilder(); errorSb.AppendLine(await response.Content.ReadAsStringAsync()); if (response.Headers.Contains("SPRequestGuid")) { var values = response.Headers.GetValues("SPRequestGuid"); if (values != null) { var spRequestGuid = values.FirstOrDefault(); errorSb.AppendLine($"ServerErrorTraceCorrelationId: {spRequestGuid}"); } } throw new Exception(errorSb.ToString()); } } return(await Task.Run(() => requestDigestString)); } }
/// <summary> /// BETA: Creates a new Modern Team Site Collection /// </summary> /// <param name="clientContext"></param> /// <param name="siteCollectionCreationInformation"></param> /// <returns></returns> public static async Task <ClientContext> CreateAsync(ClientContext clientContext, TeamSiteCollectionCreationInformation siteCollectionCreationInformation) { ClientContext responseContext = null; var accessToken = clientContext.GetAccessToken(); if (!string.IsNullOrEmpty(accessToken)) { throw new Exception("App-Only is currently not supported."); } using (var handler = new HttpClientHandler()) { // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { clientContext.Web.EnsureProperty(w => w.Url); handler.Credentials = clientContext.Credentials; handler.CookieContainer.SetCookies(new Uri(clientContext.Web.Url), (clientContext.Credentials as SharePointOnlineCredentials).GetAuthenticationCookie(new Uri(clientContext.Web.Url))); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = String.Format("{0}/_api/GroupSiteManager/CreateGroupEx", clientContext.Web.Url); Dictionary <string, object> payload = new Dictionary <string, object>(); payload.Add("displayName", siteCollectionCreationInformation.DisplayName); payload.Add("alias", siteCollectionCreationInformation.Alias); payload.Add("isPublic", siteCollectionCreationInformation.IsPublic); var optionalParams = new Dictionary <string, object>(); optionalParams.Add("Description", siteCollectionCreationInformation.Description != null ? siteCollectionCreationInformation.Description : ""); optionalParams.Add("CreationOptions", new { results = new object[0], Classification = siteCollectionCreationInformation.Classification != null ? siteCollectionCreationInformation.Classification : "" }); payload.Add("optionalParams", optionalParams); var body = payload; // Serialize request object to JSON var jsonBody = JsonConvert.SerializeObject(body); var requestBody = new StringContent(jsonBody); // Build Http request HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Content = requestBody; request.Headers.Add("accept", "application/json;odata=verbose"); MediaTypeHeaderValue sharePointJsonMediaType = null; MediaTypeHeaderValue.TryParse("application/json;odata=verbose;charset=utf-8", out sharePointJsonMediaType); requestBody.Headers.ContentType = sharePointJsonMediaType; requestBody.Headers.Add("X-RequestDigest", await clientContext.GetRequestDigest()); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); var responseJson = JObject.Parse(responseString); if (Convert.ToInt32(responseJson["d"]["CreateGroupEx"]["SiteStatus"]) == 2) { responseContext = clientContext.Clone(responseJson["d"]["CreateGroupEx"]["SiteUrl"].ToString()); } else { throw new Exception(responseString); } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } return(await Task.Run(() => responseContext)); } }