Exemple #1
0
        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;
                context.Web.EnsureProperty(w => w.Url);

                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)
                {
#pragma warning disable CA2000 // Dispose objects before losing scope
                    var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000 // Dispose objects before losing scope
                    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");

                        await PnPHttpClient.AuthenticateRequestAsync(request, context).ConfigureAwait(false);

                        // Perform actual post operation
                        HttpResponseMessage response = await httpClient.SendAsync(request, new 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));
            }
        }
Exemple #2
0
        /// <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;

            context.Web.EnsureProperty(w => w.Url);
#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000 // Dispose objects before losing scope

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

            // Always make a POST request
            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
            {
                request.Headers.Add("ACCEPT", "application/json; odata.metadata=minimal");
                request.Headers.Add("ODATA-VERSION", "4.0");

                await PnPHttpClient.AuthenticateRequestAsync(request, context).ConfigureAwait(false);

                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));
        }
Exemple #3
0
        internal static async Task <string> ExecutePostAsync(this Web web, string endpoint, string payload, string cultureLanguageName = null)
        {
            string returnObject = null;

            web.EnsureProperty(w => w.Url);

#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context: web.Context as ClientContext);
#pragma warning restore CA2000 // Dispose objects before losing scope

            var requestUrl = $"{web.Url}{endpoint}";

            using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
            {
                request.Headers.Add("accept", "application/json;odata=nometadata");

                await PnPHttpClient.AuthenticateRequestAsync(request, web.Context as ClientContext).ConfigureAwait(false);

                if (!string.IsNullOrWhiteSpace(cultureLanguageName))
                {
                    request.Headers.Add("Accept-Language", cultureLanguageName);
                }

                if (!string.IsNullOrEmpty(payload))
                {
                    var requestBody = new StringContent(payload);
                    MediaTypeHeaderValue sharePointJsonMediaType = MediaTypeHeaderValue.Parse("application/json;odata=nometadata;charset=utf-8");
                    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
                        {
                            returnObject = responseString;
                        }
                        catch { }
                    }
                }
                else
                {
                    // Something went wrong...
                    throw new Exception(await response.Content.ReadAsStringAsync());
                }
            }

            return(await Task.Run(() => returnObject));
        }
Exemple #4
0
        private static async Task <AppMetadata> GetAppMetaData(AppCatalogScope scope, ClientContext context, string id)
        {
            AppMetadata returnValue = null;
            int         retryCount  = 0;
            int         waitTime    = 10; // seconds

#pragma warning disable CA2000            // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000            // Dispose objects before losing scope

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

                await PnPHttpClient.AuthenticateRequestAsync(metadataRequest, context).ConfigureAwait(false);

                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++;
                        await Task.Delay(waitTime * 1000); // wait 10 seconds
                    }
                }
                return(returnValue);
            }
        }
Exemple #5
0
        /// <summary>
        /// Add a Webhook subscription to a SharePoint resource
        /// </summary>
        /// <param name="webUrl">Url of the site holding the list</param>
        /// <param name="resourceType">The type of Hookable SharePoint resource</param>
        /// <param name="accessToken">Access token to authenticate against SharePoint</param>
        /// <param name="context">ClientContext instance to use for authentication</param>
        /// <param name="subscription">The Webhook subscription to add</param>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when expiration date is out of valid range.</exception>
        /// <returns>The added subscription object</returns>
        public static async Task <WebhookSubscription> AddWebhookSubscriptionAsync(string webUrl, WebHookResourceType resourceType, string accessToken, ClientContext context, WebhookSubscription subscription)
        {
            if (!ValidateExpirationDateTime(subscription.ExpirationDateTime))
            {
                throw new ArgumentOutOfRangeException(nameof(subscription.ExpirationDateTime), "The specified expiration date is invalid. Should be greater than today and within 6 months");
            }

            await new SynchronizationContextRemover();

            string responseString = null;

            context.Web.EnsureProperty(p => p.Url);

#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000 // Dispose objects before losing scope

            string identifierUrl = GetResourceIdentifier(resourceType, webUrl, subscription.Resource);
            if (string.IsNullOrEmpty(identifierUrl))
            {
                throw new Exception("Identifier of the resource cannot be determined");
            }

            string requestUrl = identifierUrl + "/" + SubscriptionsUrlPart;

            using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
            {
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                await PnPHttpClient.AuthenticateRequestAsync(request, context).ConfigureAwait(false);

                request.Content = new StringContent(JsonConvert.SerializeObject(subscription), Encoding.UTF8, "application/json");

                HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken());

                if (response.IsSuccessStatusCode)
                {
                    responseString = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    // Something went wrong...
                    throw new Exception(await response.Content.ReadAsStringAsync());
                }
            }

            return(JsonConvert.DeserializeObject <WebhookSubscription>(responseString));
        }
Exemple #6
0
        /// <summary>
        /// Get all webhook subscriptions on a given SharePoint resource
        /// </summary>
        /// <param name="webUrl">Url of the site holding the resource</param>
        /// <param name="resourceType">The type of SharePoint resource</param>
        /// <param name="resourceId">The Unique Identifier of the resource</param>
        /// <param name="accessToken">Access token to authenticate against SharePoint</param>
        /// <param name="context">ClientContext instance to use for authentication</param>
        /// <returns>Collection of <see cref="WebhookSubscription"/> instances, one per returned web hook</returns>
        public static async Task <ResponseModel <WebhookSubscription> > GetWebhooksSubscriptionsAsync(string webUrl, WebHookResourceType resourceType, string resourceId, string accessToken, ClientContext context)
        {
            await new SynchronizationContextRemover();

            string responseString = null;

            context.Web.EnsureProperty(p => p.Url);
#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000 // Dispose objects before losing scope

            string identifierUrl = GetResourceIdentifier(resourceType, webUrl, resourceId);
            if (string.IsNullOrEmpty(identifierUrl))
            {
                throw new Exception("Identifier of the resource cannot be determined");
            }

            string requestUrl = identifierUrl + "/" + SubscriptionsUrlPart;

            using (var request = new HttpRequestMessage(HttpMethod.Get, requestUrl))
            {
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                await PnPHttpClient.AuthenticateRequestAsync(request, context).ConfigureAwait(false);

                HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken());

                if (response.IsSuccessStatusCode)
                {
                    responseString = await response.Content.ReadAsStringAsync();
                }
                else
                {
                    // oops...something went wrong
                    throw new Exception(await response.Content.ReadAsStringAsync());
                }
            }

            return(JsonConvert.DeserializeObject <ResponseModel <WebhookSubscription> >(responseString));
        }
Exemple #7
0
        /// <summary>
        /// Deletes an existing SharePoint web hook
        /// </summary>
        /// <param name="webUrl">Url of the site holding resource with the webhook</param>
        /// <param name="resourceType">The type of Hookable SharePoint resource</param>
        /// <param name="resourceId">Id of the resource (e.g. list id)</param>
        /// <param name="subscriptionId">Id of the web hook subscription that we need to delete</param>
        /// <param name="accessToken">Access token to authenticate against SharePoint</param>
        /// <param name="context">ClientContext instance to use for authentication</param>
        /// <returns>true if succesful, exception in case something went wrong</returns>
        public static async Task <bool> RemoveWebhookSubscriptionAsync(string webUrl, WebHookResourceType resourceType, string resourceId, string subscriptionId, string accessToken, ClientContext context)
        {
            await new SynchronizationContextRemover();

            context.Web.EnsureProperty(p => p.Url);

#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000 // Dispose objects before losing scope

            string identifierUrl = GetResourceIdentifier(resourceType, webUrl, resourceId);
            if (string.IsNullOrEmpty(identifierUrl))
            {
                throw new Exception("Identifier of the resource cannot be determined");
            }

            string requestUrl = string.Format("{0}/{1}('{2}')", identifierUrl, SubscriptionsUrlPart, subscriptionId);

            using (var request = new HttpRequestMessage(HttpMethod.Delete, requestUrl))
            {
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                await PnPHttpClient.AuthenticateRequestAsync(request, context).ConfigureAwait(false);

                HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken());

                if (response.StatusCode != HttpStatusCode.NoContent)
                {
                    // oops...something went wrong, maybe the web hook does not exist?
                    throw new Exception(await response.Content.ReadAsStringAsync());
                }
                else
                {
                    return(true);
                }
            }
        }
Exemple #8
0
        protected override void ExecuteCmdlet()
        {
            if (Url.StartsWith("/"))
            {
                // prefix the url with the current web url
                Url = UrlUtility.Combine(ClientContext.Url, Url);
            }

            var method = new HttpMethod(Method.ToString());

            var httpClient = PnPHttpClient.Instance.GetHttpClient(ClientContext);

            var requestUrl = Url;

            using (HttpRequestMessage request = new HttpRequestMessage(method, requestUrl))
            {
                request.Headers.Add("accept", "application/json;odata=nometadata");

                if (Method == HttpRequestMethod.Merge)
                {
                    request.Headers.Add("X-HTTP-Method", "MERGE");
                }

                if (Method == HttpRequestMethod.Merge || Method == HttpRequestMethod.Delete)
                {
                    request.Headers.Add("IF-MATCH", "*");
                }

                PnPHttpClient.AuthenticateRequestAsync(request, ClientContext).GetAwaiter().GetResult();

                if (Method == HttpRequestMethod.Post || Method == HttpRequestMethod.Merge || Method == HttpRequestMethod.Put || Method == HttpRequestMethod.Patch)
                {
                    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)
                    {
                        if (!Raw)
                        {
                            var jsonElement = JsonSerializer.Deserialize <JsonElement>(responseString);

                            string nextLink = string.Empty;
                            if (jsonElement.TryGetProperty("odata.nextLink", out JsonElement nextLinkProperty))
                            {
                                nextLink = nextLinkProperty.ToString();
                            }
                            if (jsonElement.TryGetProperty("value", out JsonElement valueProperty))
                            {
                                var formattedObject = ConvertToPSObject(valueProperty, "value");
                                if (!string.IsNullOrEmpty(nextLink))
                                {
                                    formattedObject.Properties.Add(new PSNoteProperty("odata.nextLink", nextLink));
                                }

                                WriteObject(formattedObject, true);
                            }
                            else
                            {
                                WriteObject(ConvertToPSObject(jsonElement, null), true);
                            }
                        }
                        else
                        {
                            WriteObject(responseString);
                        }
                    }
                }
                else
                {
                    // Something went wrong...
                    throw new Exception(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
                }
            }
        }
Exemple #9
0
        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();
#pragma warning disable CA2000 // Dispose objects before losing scope
                context = context.Clone(appcatalogUri);
#pragma warning restore CA2000 // Dispose objects before losing scope
                isCloned = true;
            }

            context.Web.EnsureProperty(w => w.Url);

#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000 // Dispose objects before losing scope

            string requestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/Add(overwrite={(overwrite.ToString().ToLower())}, url='{filename}')";

            var requestDigest = string.Empty;

            using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
            {
                request.Headers.Add("accept", "application/json;odata=nometadata");

                await PnPHttpClient.AuthenticateRequestAsync(request, context).ConfigureAwait(false);

                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 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, id);
                            }
                        }
                    }
                }
                else
                {
                    // Something went wrong...
                    throw new Exception(await response.Content.ReadAsStringAsync());
                }
            }
            if (isCloned)
            {
                context.Dispose();
            }
            return(await Task.Run(() => returnValue));
        }
Exemple #10
0
        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();
#pragma warning disable CA2000 // Dispose objects before losing scope
                context = context.Clone(appcatalogUri);
#pragma warning restore CA2000 // Dispose objects before losing scope
                isCloned = true;
            }
            var returnValue = false;

            context.Web.EnsureProperty(w => w.Url);
#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000 // Dispose objects before losing scope

            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");
                await PnPHttpClient.AuthenticateRequestAsync(request, context).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 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));
        }
Exemple #11
0
        /// <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;

            _context.Web.EnsureProperty(w => w.Url);

#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(_context);
#pragma warning restore CA2000 // Dispose objects before losing scope

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

                PnPHttpClient.AuthenticateRequestAsync(request, _context).GetAwaiter().GetResult();

                // Perform actual post operation
                HttpResponseMessage response = await httpClient.SendAsync(request, new 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>
        /// This helper method makes an HTTP request and eventually returns a result
        /// </summary>
        /// <param name="httpMethod">The HTTP method for the request</param>
        /// <param name="requestUrl">The URL of the request</param>
        /// <param name="responseHeaders">The response headers of the HTTP request (output argument)</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token for the request, if authorization is required</param>
        /// <param name="accept">The content type of the accepted response</param>
        /// <param name="content">The content of the request</param>
        /// <param name="contentType">The content  type of the request</param>
        /// <param name="referer">The URL Referer for the request</param>
        /// <param name="resultPredicate">The predicate to retrieve the result, if any</param>
        /// <param name="requestHeaders">A collection of any custom request headers</param>
        /// <param name="cookies">Any request cookies values</param>
        /// <param name="retryCount">Number of times to retry the request</param>
        /// <param name="delay">Milliseconds to wait before retrying the request. The delay will be increased (doubled) every retry</param>
        /// <param name="userAgent">UserAgent string value to insert for this request. You can define this value in your app's config file using key="SharePointPnPUserAgent" value="PnPRocks"</param>
        /// <param name="spContext">An optional SharePoint client context</param>
        /// <typeparam name="TResult">The type of the result, if any</typeparam>
        /// <returns>The value of the result, if any</returns>
        internal static TResult MakeHttpRequest <TResult>(
            string httpMethod,
            string requestUrl,
            out HttpResponseHeaders responseHeaders,
            string accessToken = null,
            string accept      = null,
            object content     = null,
            string contentType = null,
            string referer     = null,
            Func <HttpResponseMessage, TResult> resultPredicate = null,
            Dictionary <string, string> requestHeaders          = null,
            Dictionary <string, string> cookies = null,
            int retryCount          = 1,
            int delay               = 500,
            string userAgent        = null,
            ClientContext spContext = null)
        {
            //HttpClient client = HttpHelper.httpClient;
            HttpClient client;

            // Define whether to use the default HttpClient object
            if (spContext != null)
            {
#pragma warning disable CA2000 // Dispose objects before losing scope
                client = PnPHttpClient.Instance.GetHttpClient(spContext);
#pragma warning restore CA2000 // Dispose objects before losing scope
            }
            else
            {
                client = PnPHttpClient.Instance.GetHttpClient();
            }

            // Prepare the variable to hold the result, if any
            TResult result = default;
            responseHeaders = null;

            if (!string.IsNullOrEmpty(referer))
            {
                client.DefaultRequestHeaders.Referrer = new Uri(referer);
            }

            // If there is an accept argument, set the corresponding HTTP header
            if (!string.IsNullOrEmpty(accept))
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue(accept));
            }

            // Process any additional custom request headers
            if (requestHeaders != null)
            {
                foreach (var requestHeader in requestHeaders)
                {
                    client.DefaultRequestHeaders.Add(requestHeader.Key, requestHeader.Value);
                }
            }

            // Prepare the content of the request, if any
            HttpContent      requestContent = null;
            System.IO.Stream streamContent  = content as System.IO.Stream;
            if (streamContent != null)
            {
                requestContent = new StreamContent(streamContent);
                requestContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
            }
            else if (content != null)
            {
                var jsonString = content is string
                                 ?content.ToString()
                                     : JsonConvert.SerializeObject(content, Formatting.None, new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    ContractResolver  = new ODataBindJsonResolver(),
                });

                requestContent = new StringContent(jsonString, Encoding.UTF8, contentType);
            }

            // Prepare the HTTP request message with the proper HTTP method
            using (HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(httpMethod), requestUrl))
            {
                // Set the request content, if any
                if (requestContent != null)
                {
                    request.Content = requestContent;
                }

                if (spContext != null)
                {
                    PnPHttpClient.AuthenticateRequestAsync(request, spContext).GetAwaiter().GetResult();
                }
                else
                {
                    PnPHttpClient.AuthenticateRequest(request, accessToken);
                }

                // Fire the HTTP request
                HttpResponseMessage response = client.SendAsync(request).Result;

                if (response.IsSuccessStatusCode)
                {
                    // If the response is Success and there is a
                    // predicate to retrieve the result, invoke it
                    if (resultPredicate != null)
                    {
                        result = resultPredicate(response);
                    }

                    // Get any response header and put it in the answer
                    responseHeaders = response.Headers;
                }
                else
                {
                    throw new ApplicationException(
                              string.Format("Exception while invoking endpoint {0}.", requestUrl),
                              new Exception(response.Content.ReadAsStringAsync().Result));
                }
            }

            return(result);
        }
Exemple #13
0
        /// <summary>
        /// Updates the expiration datetime (and notification URL) of an existing SharePoint web hook
        /// </summary>
        /// <param name="webUrl">Url of the site holding resource with the webhook</param>
        /// <param name="resourceType">The type of Hookable SharePoint resource</param>
        /// <param name="resourceId">Id of the resource (e.g. list id)</param>
        /// <param name="subscriptionId">Id of the web hook subscription that we need to delete</param>
        /// <param name="webHookEndPoint">Url of the web hook service endpoint (the one that will be called during an event)</param>
        /// <param name="expirationDateTime">New web hook expiration date</param>
        /// <param name="accessToken">Access token to authenticate against SharePoint</param>
        /// <param name="context">ClientContext instance to use for authentication</param>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when expiration date is out of valid range.</exception>
        /// <returns>true if succesful, exception in case something went wrong</returns>
        public static async Task <bool> UpdateWebhookSubscriptionAsync(string webUrl, WebHookResourceType resourceType, string resourceId, string subscriptionId,
                                                                       string webHookEndPoint, DateTime expirationDateTime, string accessToken, ClientContext context)
        {
            if (!ValidateExpirationDateTime(expirationDateTime))
            {
                throw new ArgumentOutOfRangeException(nameof(expirationDateTime), "The specified expiration date is invalid. Should be greater than today and within 6 months");
            }

            await new SynchronizationContextRemover();

            context.Web.EnsureProperty(p => p.Url);

#pragma warning disable CA2000 // Dispose objects before losing scope
            var httpClient = PnPHttpClient.Instance.GetHttpClient(context);
#pragma warning restore CA2000 // Dispose objects before losing scope

            string identifierUrl = GetResourceIdentifier(resourceType, webUrl, resourceId);
            if (string.IsNullOrEmpty(identifierUrl))
            {
                throw new Exception("Identifier of the resource cannot be determined");
            }

            string requestUrl = string.Format("{0}/{1}('{2}')", identifierUrl, SubscriptionsUrlPart, subscriptionId);
            using (var request = new HttpRequestMessage(new HttpMethod("PATCH"), requestUrl))
            {
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                await PnPHttpClient.AuthenticateRequestAsync(request, context).ConfigureAwait(false);

                WebhookSubscription webhookSubscription;

                if (string.IsNullOrEmpty(webHookEndPoint))
                {
                    webhookSubscription = new WebhookSubscription()
                    {
                        ExpirationDateTime = expirationDateTime
                    };
                }
                else
                {
                    webhookSubscription = new WebhookSubscription()
                    {
                        NotificationUrl    = webHookEndPoint,
                        ExpirationDateTime = expirationDateTime
                    };
                }

                request.Content = new StringContent(JsonConvert.SerializeObject(webhookSubscription),
                                                    Encoding.UTF8, "application/json");

                HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken());

                if (response.StatusCode != HttpStatusCode.NoContent)
                {
                    // oops...something went wrong, maybe the web hook does not exist?
                    throw new Exception(await response.Content.ReadAsStringAsync());
                }
                else
                {
                    return(true);
                }
            }
        }