/// <summary> /// Extends a <see cref="PnPContext"/> with Microsoft 365 admin functionality /// </summary> /// <param name="context"><see cref="PnPContext"/> to extend</param> /// <returns>An <see cref="IMicrosoft365Admin"/> instance enabling Microsoft 365 admin operations</returns> public static IMicrosoft365Admin GetMicrosoft365Admin(this PnPContext context) { return(new Microsoft365Admin(context)); }
/// <summary> /// Extends a <see cref="PnPContext"/> with tenant Application Lifecycle Management (ALM) functionality /// </summary> /// <param name="context"><see cref="PnPContext"/> to extend</param> /// <returns>An <see cref="ITenantAppManager"/> instance enabling tenant app catalog operations</returns> public static ITenantAppManager GetTenantAppManager(this PnPContext context) { return(new TenantAppManager(context)); }
/// <summary> /// Extends a <see cref="PnPContext"/> with site collection Application Lifecycle Management (ALM) functionality /// </summary> /// <param name="context"><see cref="PnPContext"/> to extend</param> /// <returns>An <see cref="ISiteCollectionAppManager"/> instance enabling site collection app catalog operations</returns> public static ISiteCollectionAppManager GetSiteCollectionAppManager(this PnPContext context) { return(new SiteCollectionAppManager(context)); }
/// <summary> /// Method to resolve a set of tokens in a provided tokenized string /// </summary> /// <param name="tokenizedValue">A string with tokens</param> /// <param name="pnpObject">The domain model object to use as the target reference</param> /// <param name="context"><see cref="PnPContext"/> to get information from needed for token resolving</param> /// <returns>The string with tokens resolved</returns> public static async Task <string> ResolveTokensAsync(IMetadataExtensible pnpObject, string tokenizedValue, PnPContext context = null) { // Define the result variable string result = tokenizedValue; // Get the context aware version of the target pnpObject var contextAwareObject = pnpObject as IDataModelWithContext; // If we don't have an input context, let's try to use // the one associated with the input entity, if any if (context == null && contextAwareObject != null) { context = contextAwareObject.PnPContext; } // Grab the tokens in this input (tokens are between curly braces) var matches = regex.Matches(tokenizedValue); // Iterate over the tokens and replace them foreach (Match match in matches) { // Replace {Id} if (match.Value.Equals("{Id}")) { var model = pnpObject; if (model.Metadata.ContainsKey(PnPConstants.MetaDataRestId)) { result = result.Replace("{Id}", model.Metadata[PnPConstants.MetaDataRestId]); } } // Replace {Parent.Id} else if (match.Value.Equals("{Parent.Id}")) { // there's either a collection object inbetween (e.g. ListItem --> ListItemCollection --> List), so take the parent of the parent // or // the parent is model class itself (e.g. Web --> Site.RootWeb) IDataModelParent parent = GetParentDataModel(pnpObject); // Ensure the parent object if (parent != null) { await((IDataModelParent)pnpObject).EnsureParentObjectAsync().ConfigureAwait(true); } if (parent is IMetadataExtensible p) { if (p.Metadata.ContainsKey(PnPConstants.MetaDataRestId)) { result = result.Replace("{Parent.Id}", p.Metadata[PnPConstants.MetaDataRestId]); } } } // Replace {GraphId} else if (match.Value.Equals("{GraphId}")) { var model = pnpObject; if (model.Metadata.ContainsKey(PnPConstants.MetaDataGraphId)) { result = result.Replace("{GraphId}", model.Metadata[PnPConstants.MetaDataGraphId]); } } // Replace {Parent.GraphId} else if (match.Value.Equals("{Parent.GraphId}")) { // there's either a collection object inbetween (e.g. TeamChannel --> TeamChannelCollection --> Team), so take the parent of the parent // or // the parent is model class itself (e.g. TeamChannel --> Team.PrimaryChannel) IDataModelParent parent = GetParentDataModel(pnpObject); // Ensure the parent object if (parent != null) { await((IDataModelParent)pnpObject).EnsureParentObjectAsync().ConfigureAwait(true); } if (parent is IMetadataExtensible p) { if (p.Metadata.ContainsKey(PnPConstants.MetaDataGraphId)) { result = result.Replace("{Parent.GraphId}", p.Metadata[PnPConstants.MetaDataGraphId]); } } } // Replace tokens coming from the Site object connected to the current PnPContext else if (match.Value.StartsWith("{Site.") && context != null) { var propertyToLoad = match.Value.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1].Replace("}", ""); switch (propertyToLoad) { case "GroupId": { await context.Site.EnsurePropertiesAsync(p => p.GroupId).ConfigureAwait(false); if (context.Site.HasValue(propertyToLoad)) { result = result.Replace(match.Value, context.Site.GroupId.ToString()); } break; } case "Id": { await context.Site.EnsurePropertiesAsync(p => p.Id).ConfigureAwait(false); if (context.Site.HasValue(propertyToLoad)) { result = result.Replace(match.Value, context.Site.Id.ToString()); } break; } case "Url": { await context.Site.EnsurePropertiesAsync(p => p.Url).ConfigureAwait(false); if (context.Site.HasValue(propertyToLoad)) { result = result.Replace(match.Value, context.Site.Url.ToString()); } break; } case "HubSiteId": { await context.Site.EnsurePropertiesAsync(p => p.HubSiteId).ConfigureAwait(false); if (context.Site.HasValue(propertyToLoad)) { result = result.Replace(match.Value, context.Site.HubSiteId.ToString()); } break; } } } // Replace tokens coming from the Web object connected to the current PnPContext else if (match.Value.StartsWith("{Web.") && context != null) { var propertyToLoad = match.Value.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1].Replace("}", ""); switch (propertyToLoad) { case "Id": { await context.Web.EnsurePropertiesAsync(p => p.Id).ConfigureAwait(false); if (context.Web.HasValue(propertyToLoad)) { result = result.Replace(match.Value, context.Web.Id.ToString()); } break; } case "GraphId": { var model = context.Web as IMetadataExtensible; if (model.Metadata.ContainsKey(PnPConstants.MetaDataGraphId)) { result = result.Replace("{Web.GraphId}", model.Metadata[PnPConstants.MetaDataGraphId]); } break; } } } // Replace tokens coming from the List object connected to the current PnPContext else if (match.Value.StartsWith("{List.") && context != null) { var propertyToLoad = match.Value.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1].Replace("}", ""); switch (propertyToLoad) { case "Id": { // Try to see if the current object is a list var list = pnpObject as Model.SharePoint.IList; // If the object is a list item if (list == null) { if (pnpObject is Model.SharePoint.IListItem listItem) { // Get the parent list of the current list item list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList; // Option A: the file has the ListId property loaded if (list == null && GetParentDataModel(listItem as IMetadataExtensible) is Model.SharePoint.IFile file && file.IsPropertyAvailable(p => p.ListId)) { result = result.Replace(match.Value, file.ListId.ToString()); break; } // Option B: the IListItem has a property that indicates the used list if (list == null && (listItem as IMetadataExtensible).Metadata.ContainsKey(PnPConstants.MetaDataListId)) { result = result.Replace(match.Value, (listItem as IMetadataExtensible).Metadata[PnPConstants.MetaDataListId]); break; } } else if (pnpObject is Model.SharePoint.IFile file) { listItem = GetParentDataModel(file as IMetadataExtensible) as Model.SharePoint.IListItem; list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList; } else if (pnpObject is Model.SharePoint.IFileVersion fileVersion) { if (fileVersion.Parent is Model.SharePoint.IFile) { var fileVersionfile = GetParentDataModel(fileVersion as IMetadataExtensible) as Model.SharePoint.IFile; listItem = GetParentDataModel(fileVersionfile as IMetadataExtensible) as Model.SharePoint.IListItem; } else if (fileVersion.Parent is Model.SharePoint.IListItemVersion) { var listItemVersion = GetParentDataModel(fileVersion as IMetadataExtensible) as Model.SharePoint.IListItemVersion; listItem = GetParentDataModel(listItemVersion as IMetadataExtensible) as Model.SharePoint.IListItem; } else { listItem = null; } list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList; } else if (pnpObject is Model.SharePoint.IListItemVersion listItemVersion) { listItem = GetParentDataModel(listItemVersion as IMetadataExtensible) as Model.SharePoint.IListItem; list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList; } else if (pnpObject is Model.SharePoint.IComment comment) { listItem = GetParentDataModel(comment as IMetadataExtensible) as Model.SharePoint.IListItem; if (listItem == null) { // comment was a reply to another comment var parentComment = GetParentDataModel(comment as IMetadataExtensible) as Model.SharePoint.IComment; listItem = GetParentDataModel(parentComment as IMetadataExtensible) as Model.SharePoint.IListItem; } // the IListItem has a property that indicates the used list if (listItem != null && (listItem as IMetadataExtensible).Metadata.ContainsKey(PnPConstants.MetaDataListId)) { result = result.Replace(match.Value, (listItem as IMetadataExtensible).Metadata[PnPConstants.MetaDataListId]); break; } list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList; } else if (pnpObject is Model.SharePoint.IAttachment attachment) { listItem = GetParentDataModel(attachment as IMetadataExtensible) as Model.SharePoint.IListItem; list = GetParentDataModel(listItem as IMetadataExtensible) as Model.SharePoint.IList; } } // If we've got the list if (list != null) { // We retrieve the Id and we use it as the token value await list.EnsurePropertiesAsync(l => l.Id).ConfigureAwait(false); result = result.Replace(match.Value, list.Id.ToString()); } break; } } } // Replace tokens coming from the List Item object connected to the current PnPContext else if (match.Value.StartsWith("{Item.") && context != null) { var propertyToLoad = match.Value.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries)[1].Replace("}", ""); switch (propertyToLoad) { case "Id": { // Try to see if the current object is a list item var listItem = pnpObject as Model.SharePoint.IListItem; // If the object is a descendant of a list item if (listItem == null) { var model = pnpObject; if (model is Model.SharePoint.IFileVersion) { // Should return either an IListItemVersion or an IFile model = GetParentDataModel(model) as IMetadataExtensible; } if (model is Model.SharePoint.IFile || model is Model.SharePoint.IListItemVersion) { // Should return an IListItem listItem = GetParentDataModel(model) as Model.SharePoint.IListItem; } } // If we've got the list item if (listItem != null) { // We retrieve the Id and we use it as the token value await listItem.EnsurePropertiesAsync(l => l.Id).ConfigureAwait(false); result = result.Replace(match.Value, listItem.Id.ToString()); } break; } } } // Replace {hostname} else if (match.Value.Equals("{hostname}")) { result = result.Replace("{hostname}", context.Uri.DnsSafeHost); } // Replace {serverrelativepath} else if (match.Value.Equals("{serverrelativepath}")) { result = result.Replace("{serverrelativepath}", context.Uri.PathAndQuery); } } return(result); }
/// <summary> /// Extends a <see cref="PnPContext"/> with SharePoint admin functionality /// </summary> /// <param name="context"><see cref="PnPContext"/> to extend</param> /// <returns>An <see cref="ISharePointAdmin"/> instance enabling SharePoint admin operations</returns> public static ISharePointAdmin GetSharePointAdmin(this PnPContext context) { return(new SharePointAdmin(context)); }
internal static async Task CopyContextInitializationAsync(PnPContext source, PnPContext target) { if (source.Web.IsPropertyAvailable(p => p.Id) && source.Web.IsPropertyAvailable(p => p.Url) && source.Web.IsPropertyAvailable(p => p.RegionalSettings) && source.Site.IsPropertyAvailable(p => p.Id) && source.Site.IsPropertyAvailable(p => p.GroupId)) { target.Web.SetSystemProperty(p => p.Id, source.Web.Id); target.Web.SetSystemProperty(p => p.Url, source.Web.Url); target.Web.Requested = true; (target.Web as Web).Metadata = new Dictionary <string, string>((source.Web as Web).Metadata); // Copy regional settings, important to trigger the creation of the regional settings model from the target web model var regionalSettings = target.Web.RegionalSettings; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.AM)) { regionalSettings.SetSystemProperty(p => p.AM, source.Web.RegionalSettings.AM); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.CollationLCID)) { regionalSettings.SetSystemProperty(p => p.CollationLCID, source.Web.RegionalSettings.CollationLCID); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DateFormat)) { regionalSettings.SetSystemProperty(p => p.DateFormat, source.Web.RegionalSettings.DateFormat); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DateSeparator)) { regionalSettings.SetSystemProperty(p => p.DateSeparator, source.Web.RegionalSettings.DateSeparator); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DecimalSeparator)) { regionalSettings.SetSystemProperty(p => p.DecimalSeparator, source.Web.RegionalSettings.DecimalSeparator); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DigitGrouping)) { regionalSettings.SetSystemProperty(p => p.DigitGrouping, source.Web.RegionalSettings.DigitGrouping); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.FirstDayOfWeek)) { regionalSettings.SetSystemProperty(p => p.FirstDayOfWeek, source.Web.RegionalSettings.FirstDayOfWeek); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsEastAsia)) { regionalSettings.SetSystemProperty(p => p.IsEastAsia, source.Web.RegionalSettings.IsEastAsia); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsRightToLeft)) { regionalSettings.SetSystemProperty(p => p.IsRightToLeft, source.Web.RegionalSettings.IsRightToLeft); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsUIRightToLeft)) { regionalSettings.SetSystemProperty(p => p.IsUIRightToLeft, source.Web.RegionalSettings.IsUIRightToLeft); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ListSeparator)) { regionalSettings.SetSystemProperty(p => p.ListSeparator, source.Web.RegionalSettings.ListSeparator); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.LocaleId)) { regionalSettings.SetSystemProperty(p => p.LocaleId, source.Web.RegionalSettings.LocaleId); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.NegativeSign)) { regionalSettings.SetSystemProperty(p => p.NegativeSign, source.Web.RegionalSettings.NegativeSign); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.NegNumberMode)) { regionalSettings.SetSystemProperty(p => p.NegNumberMode, source.Web.RegionalSettings.NegNumberMode); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.PM)) { regionalSettings.SetSystemProperty(p => p.PM, source.Web.RegionalSettings.PM); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.PositiveSign)) { regionalSettings.SetSystemProperty(p => p.PositiveSign, source.Web.RegionalSettings.PositiveSign); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ShowWeeks)) { regionalSettings.SetSystemProperty(p => p.ShowWeeks, source.Web.RegionalSettings.ShowWeeks); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ThousandSeparator)) { regionalSettings.SetSystemProperty(p => p.ThousandSeparator, source.Web.RegionalSettings.ThousandSeparator); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.Time24)) { regionalSettings.SetSystemProperty(p => p.Time24, source.Web.RegionalSettings.Time24); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.TimeMarkerPosition)) { regionalSettings.SetSystemProperty(p => p.TimeMarkerPosition, source.Web.RegionalSettings.TimeMarkerPosition); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.TimeSeparator)) { regionalSettings.SetSystemProperty(p => p.TimeSeparator, source.Web.RegionalSettings.TimeSeparator); } ; regionalSettings.Requested = true; (regionalSettings as RegionalSettings).Metadata = new Dictionary <string, string>((source.Web.RegionalSettings as RegionalSettings).Metadata); // Copy timezone settings var timeZone = regionalSettings.TimeZone; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Description)) { timeZone.SetSystemProperty(p => p.Description, source.Web.RegionalSettings.TimeZone.Description); } ; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Id)) { timeZone.SetSystemProperty(p => p.Id, source.Web.RegionalSettings.TimeZone.Id); } ; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Bias)) { timeZone.SetSystemProperty(p => p.Bias, source.Web.RegionalSettings.TimeZone.Bias); } ; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.DaylightBias)) { timeZone.SetSystemProperty(p => p.DaylightBias, source.Web.RegionalSettings.TimeZone.DaylightBias); } ; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.StandardBias)) { timeZone.SetSystemProperty(p => p.StandardBias, source.Web.RegionalSettings.TimeZone.StandardBias); } ; timeZone.Requested = true; (timeZone as Model.SharePoint.TimeZone).Metadata = new Dictionary <string, string>((source.Web.RegionalSettings.TimeZone as Model.SharePoint.TimeZone).Metadata); // Copy site settings target.Site.SetSystemProperty(p => p.Id, source.Site.Id); target.Site.SetSystemProperty(p => p.GroupId, source.Site.GroupId); target.Site.Requested = true; (target.Site as Site).Metadata = new Dictionary <string, string>((source.Site as Site).Metadata); // Copy the additional initialization properties (if any) // Only "basic" properties are cloned, complex properties (e.g. Web.Lists) are not cloned as // a common use case of using a cloned context is to start "clean", basic web/site properties do not change // when cloning for the same site url, but one might want to load collections (= complex property) // using a different filter if (source.LocalContextOptions != null) { List <Expression <Func <ISite, object> > > clonedSiteProperties = new List <Expression <Func <ISite, object> > >(); List <Expression <Func <IWeb, object> > > clonedWebProperties = new List <Expression <Func <IWeb, object> > >(); if (source.LocalContextOptions.AdditionalSitePropertiesOnCreate != null) { foreach (var prop in source.LocalContextOptions.AdditionalSitePropertiesOnCreate) { if (!prop.Body.Type.ImplementsInterface(typeof(IDataModelParent)) && !prop.Body.Type.ImplementsInterface(typeof(IQueryable))) { clonedSiteProperties.Add(prop); target.Site.SetSystemProperty(prop, GetPropertyValue(source.Site, prop)); } } } if (source.LocalContextOptions.AdditionalWebPropertiesOnCreate != null) { foreach (var prop in source.LocalContextOptions.AdditionalWebPropertiesOnCreate) { if (!prop.Body.Type.ImplementsInterface(typeof(IDataModelParent)) && !prop.Body.Type.ImplementsInterface(typeof(IQueryable))) { clonedWebProperties.Add(prop); target.Web.SetSystemProperty(prop, GetPropertyValue(source.Web, prop)); } } } if (clonedSiteProperties.Any() || clonedWebProperties.Any()) { target.LocalContextOptions = new PnPContextOptions() { AdditionalSitePropertiesOnCreate = clonedSiteProperties.Any() ? clonedSiteProperties : null, AdditionalWebPropertiesOnCreate = clonedWebProperties.Any() ? clonedWebProperties : null }; } } } else { // seems the data in the source context was not what we expected, run the usual initialization to reset it, reuse the source context options // if specified await InitializeContextAsync(target, source.LocalContextOptions).ConfigureAwait(false); } }
private async Task SendBlazorInitEventAsync(PnPContext context) { try { // Ensure the tenant id was fetched await context.SetAADTenantId().ConfigureAwait(false); using (var request = new HttpRequestMessage(HttpMethod.Post, $"https://dc.services.visualstudio.com/v2/track")) { // Build payload var body = new { name = "AppEvents", time = DateTime.Now.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffZ"), iKey = TelemetryManager.InstrumentationKey, data = new { baseType = "EventData", baseData = new { ver = 2, name = "PnPCoreInit", properties = new { PnPCoreSDKVersion = "1.0.0.0", AADTenantId = GlobalOptions.AADTenantId.ToString(), OS = "WASM" } } } }; var jsonBody = JsonSerializer.Serialize(body, PnPConstants.JsonSerializer_IgnoreNullValues); using (StringContent content = new StringContent(jsonBody)) { // Remove the default Content-Type content header if (content.Headers.Contains("Content-Type")) { content.Headers.Remove("Content-Type"); } // Add the batch Content-Type header content.Headers.Add($"Content-Type", "application/x-json-stream"); // Connect content to request request.Content = content; HttpResponseMessage response = await httpClient.SendAsync(request).ConfigureAwait(false); if (!response.IsSuccessStatusCode) { Log.LogDebug($"Blazor telemetry failure: {await response.Content.ReadAsStringAsync().ConfigureAwait(false)}"); } } } } // Never fail if telemetry is failing #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { Log.LogDebug($"Blazor telemetry failure: {ex}"); } }
private static string GetPropertiesFile(PnPContext context) { return(Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}.properties")); }
/// <summary> /// When using REST batch requests the URL needs to be correctly cased, so we're loading the web url while doing an interactive request. /// Also loading the default needed properties to save additional loads for missing key properties /// </summary> /// <param name="context">PnPContext being initialized</param> /// <param name="options">Options for the initialization of this context</param> /// <returns></returns> internal static async Task InitializeContextAsync(PnPContext context, PnPContextOptions options) { // Set environment if not yet set if (!context.Environment.HasValue) { context.Environment = CloudManager.GetEnvironmentFromUri(context.Uri); // Ensure the Microsoft Graph URL is set depending on the used cloud environment context.GraphClient.UpdateBaseAddress(CloudManager.GetMicrosoftGraphAuthority(context.Environment.Value)); } // Store the provided options, needed for context cloning context.LocalContextOptions = options; // IMPORTANT: this first call is an interactive call by design as that allows us set the // web URL using the correct casing. Correct casing is required in REST batching // IMPORTANT: if you change this logic by adding more initialization data you also need // to update the CopyContextInitialization method! // Combine the default properties to load with optional additional properties var(siteProps, webProps) = GetDefaultPropertiesToLoad(options); // Use the query client to build the correct initialization query for the given Web properties BaseDataModel <IWeb> concreteEntity = EntityManager.GetEntityConcreteInstance(typeof(IWeb), context.Web, context) as BaseDataModel <IWeb>; var entityInfo = EntityManager.GetClassInfo(concreteEntity.GetType(), concreteEntity, null, webProps.ToArray()); var apiCallRequest = await QueryClient.BuildGetAPICallAsync(concreteEntity, entityInfo, new ApiCall($"_api/Web", ApiType.SPORest), true).ConfigureAwait(false); // Load required web properties var api = new ApiCall(apiCallRequest.ApiCall.Request, ApiType.SPORest) { Interactive = true }; await(context.Web as Web).RequestAsync(api, HttpMethod.Get, "Get").ConfigureAwait(false); // Replace the context URI with the value using the correct casing context.Uri = context.Web.Url; // Request the site properties await context.Site.LoadAsync(siteProps.ToArray()).ConfigureAwait(false); // Ensure the Graph ID is set once and only once if (context.Web is IMetadataExtensible me) { if (!me.Metadata.ContainsKey(PnPConstants.MetaDataGraphId)) { me.Metadata.Add(PnPConstants.MetaDataGraphId, $"{context.Uri.DnsSafeHost},{context.Site.Id},{context.Web.Id}"); } } // If the GroupId is available ensure it's also correctly set on the Group metadata so that calls via that // model can work if (context.Site.IsPropertyAvailable(p => p.GroupId) && context.Site.GroupId != Guid.Empty) { if (context.Group is IMetadataExtensible groupMetaData) { if (!groupMetaData.Metadata.ContainsKey(PnPConstants.MetaDataGraphId)) { groupMetaData.Metadata.Add(PnPConstants.MetaDataGraphId, context.Site.GroupId.ToString()); } } } }
private static string GetResponseFile(PnPContext context, string orderPrefix) { return(Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}-{orderPrefix}.response.json")); }
private static string GetDebugFile(PnPContext context, string orderPrefix) { return(Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}-{orderPrefix}.debug")); }
internal static async Task CopyContextInitializationAsync(PnPContext source, PnPContext target) { if (source.Web.IsPropertyAvailable(p => p.Id) && source.Web.IsPropertyAvailable(p => p.Url) && source.Web.IsPropertyAvailable(p => p.RegionalSettings) && source.Site.IsPropertyAvailable(p => p.Id) && source.Site.IsPropertyAvailable(p => p.GroupId)) { target.Web.SetSystemProperty(p => p.Id, source.Web.Id); target.Web.SetSystemProperty(p => p.Url, source.Web.Url); target.Web.Requested = true; (target.Web as Web).Metadata = new System.Collections.Generic.Dictionary <string, string>((source.Web as Web).Metadata); // Copy regional settings, important to trigger the creation of the regional settings model from the target web model var regionalSettings = target.Web.RegionalSettings; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.AM)) { regionalSettings.SetSystemProperty(p => p.AM, source.Web.RegionalSettings.AM); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.CollationLCID)) { regionalSettings.SetSystemProperty(p => p.CollationLCID, source.Web.RegionalSettings.CollationLCID); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DateFormat)) { regionalSettings.SetSystemProperty(p => p.DateFormat, source.Web.RegionalSettings.DateFormat); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DateSeparator)) { regionalSettings.SetSystemProperty(p => p.DateSeparator, source.Web.RegionalSettings.DateSeparator); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DecimalSeparator)) { regionalSettings.SetSystemProperty(p => p.DecimalSeparator, source.Web.RegionalSettings.DecimalSeparator); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.DigitGrouping)) { regionalSettings.SetSystemProperty(p => p.DigitGrouping, source.Web.RegionalSettings.DigitGrouping); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.FirstDayOfWeek)) { regionalSettings.SetSystemProperty(p => p.FirstDayOfWeek, source.Web.RegionalSettings.FirstDayOfWeek); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsEastAsia)) { regionalSettings.SetSystemProperty(p => p.IsEastAsia, source.Web.RegionalSettings.IsEastAsia); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsRightToLeft)) { regionalSettings.SetSystemProperty(p => p.IsRightToLeft, source.Web.RegionalSettings.IsRightToLeft); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.IsUIRightToLeft)) { regionalSettings.SetSystemProperty(p => p.IsUIRightToLeft, source.Web.RegionalSettings.IsUIRightToLeft); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ListSeparator)) { regionalSettings.SetSystemProperty(p => p.ListSeparator, source.Web.RegionalSettings.ListSeparator); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.LocaleId)) { regionalSettings.SetSystemProperty(p => p.LocaleId, source.Web.RegionalSettings.LocaleId); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.NegativeSign)) { regionalSettings.SetSystemProperty(p => p.NegativeSign, source.Web.RegionalSettings.NegativeSign); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.NegNumberMode)) { regionalSettings.SetSystemProperty(p => p.NegNumberMode, source.Web.RegionalSettings.NegNumberMode); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.PM)) { regionalSettings.SetSystemProperty(p => p.PM, source.Web.RegionalSettings.PM); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.PositiveSign)) { regionalSettings.SetSystemProperty(p => p.PositiveSign, source.Web.RegionalSettings.PositiveSign); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ShowWeeks)) { regionalSettings.SetSystemProperty(p => p.ShowWeeks, source.Web.RegionalSettings.ShowWeeks); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.ThousandSeparator)) { regionalSettings.SetSystemProperty(p => p.ThousandSeparator, source.Web.RegionalSettings.ThousandSeparator); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.Time24)) { regionalSettings.SetSystemProperty(p => p.Time24, source.Web.RegionalSettings.Time24); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.TimeMarkerPosition)) { regionalSettings.SetSystemProperty(p => p.TimeMarkerPosition, source.Web.RegionalSettings.TimeMarkerPosition); } ; if (source.Web.RegionalSettings.IsPropertyAvailable(p => p.TimeSeparator)) { regionalSettings.SetSystemProperty(p => p.TimeSeparator, source.Web.RegionalSettings.TimeSeparator); } ; regionalSettings.Requested = true; (regionalSettings as RegionalSettings).Metadata = new System.Collections.Generic.Dictionary <string, string>((source.Web.RegionalSettings as RegionalSettings).Metadata); // Copy timezone settings var timeZone = regionalSettings.TimeZone; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Description)) { timeZone.SetSystemProperty(p => p.Description, source.Web.RegionalSettings.TimeZone.Description); } ; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Id)) { timeZone.SetSystemProperty(p => p.Id, source.Web.RegionalSettings.TimeZone.Id); } ; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.Bias)) { timeZone.SetSystemProperty(p => p.Bias, source.Web.RegionalSettings.TimeZone.Bias); } ; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.DaylightBias)) { timeZone.SetSystemProperty(p => p.DaylightBias, source.Web.RegionalSettings.TimeZone.DaylightBias); } ; if (source.Web.RegionalSettings.TimeZone.IsPropertyAvailable(p => p.StandardBias)) { timeZone.SetSystemProperty(p => p.StandardBias, source.Web.RegionalSettings.TimeZone.StandardBias); } ; timeZone.Requested = true; (timeZone as Model.SharePoint.TimeZone).Metadata = new System.Collections.Generic.Dictionary <string, string>((source.Web.RegionalSettings.TimeZone as Model.SharePoint.TimeZone).Metadata); // Copy site settings target.Site.SetSystemProperty(p => p.Id, source.Site.Id); target.Site.SetSystemProperty(p => p.GroupId, source.Site.GroupId); target.Site.Requested = true; (target.Site as Site).Metadata = new System.Collections.Generic.Dictionary <string, string>((source.Site as Site).Metadata); } else { // seems the data in the source context was not what we expected, run the usual initialization to reset it await InitializeContextAsync(target).ConfigureAwait(false); } }
/// <summary> /// Mocks the response for a given request /// </summary> /// <param name="context">Current PnPContext</param> /// <param name="requestKey">Key we used to calculate the hash, used to identify the response to return</param> /// <returns>Server response from the mock response</returns> internal static Stream MockResponseAsStream(PnPContext context, string requestKey) { return(MockResponse(context, requestKey).AsStream()); }
private static string GetDebugFile(PnPContext context, /*string hash,*/ string orderPrefix) { //return Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}-{orderPrefix}-{hash}.debug"); return(Path.Combine(GetPath(context), $"{context.TestName}-{context.TestId}-{orderPrefix}.debug")); }
internal Dictionary <string, string> PopulateRequestProperties(BatchRequest request, PnPContext context) { Dictionary <string, string> properties = new Dictionary <string, string>(10) { { "PnPCoreSDKVersion", Version }, { "AADTenantId", GlobalOptions.AADTenantId.ToString() }, { "Model", request.Model.GetType().FullName }, { "ApiType", request.ApiCall.Type.ToString() }, { "ApiMethod", request.Method.ToString() }, { "GraphFirst", context.GraphFirst.ToString() }, { "GraphCanUseBeta", context.GraphCanUseBeta.ToString() }, { "GraphAlwaysUseBeta", context.GraphAlwaysUseBeta.ToString() }, { "OS", GetOSVersion() }, { "Operation", request.OperationName }, }; return(properties); }
internal virtual void LogServiceRequest(BatchRequest request, PnPContext context) { TelemetryClient.TrackEvent("PnPCoreRequest", PopulateRequestProperties(request, context)); }