/// <summary> /// Authenticate using the special service library for SharePoint Online / Office 365. /// </summary> public void SetCredentialsForCloud(string userEmail, SecureString password, Action <string> logVerbose = null) { CsomHelpers.LoadOnlineServiceLibrary(logVerbose); var credential = new SharePointOnlineCredentials(userEmail, password); this.clientContext.Credentials = credential; }
private void DetermineLcidsToProcess() { CsomHelpers.FlushCachedProperties(this.clientTermStore); this.ClientConnector.ClientContext.Load(this.clientTermStore, ts => ts.Languages, ts => ts.DefaultLanguage); this.ClientConnector.ExecuteQuery(); if (this.localTermStore.DefaultLanguageLcid != this.clientTermStore.DefaultLanguage) { throw new InvalidOperationException( "The SharePoint term store default language does not match the LocalTermStore default language"); } this.clientLcids.Clear(); this.clientLcids.AddRange(this.clientTermStore.Languages); this.clientLcids.Sort(); this.clientLcidsHashSet.Clear(); foreach (int lcid in this.clientLcids) { this.clientLcidsHashSet.Add(lcid); } this.localLcids.Clear(); this.localLcids.AddRange(this.localTermStore.AvailableLanguageLcids); this.localLcids.Sort(); }
// This is not a property because it may set up a CSOM query. public TaxonomySession GetTaxonomySession() { if (this.taxonomySession == null) { this.taxonomySession = TaxonomySession.GetTaxonomySession(this.clientContext); } CsomHelpers.FlushCachedProperties(this.taxonomySession); CsomHelpers.FlushCachedProperties(this.taxonomySession.TermStores); return(this.taxonomySession); }
protected override bool OnProcessCheckExistence() { this.clientTermGroup = null; // We need this in case g.TermSets.Include() pulls in the TermSet.Name this.SetClientWorkingLanguageToDefault(); this.exceptionHandlingScope = new ExceptionHandlingScope(this.ClientContext); using (this.exceptionHandlingScope.StartScope()) { using (this.exceptionHandlingScope.StartTry()) { TermStore clientTermStore = this.ClientTermStore; CsomHelpers.FlushCachedProperties(clientTermStore.Groups); if (this.FindByName) { this.clientTermGroup = clientTermStore.Groups .GetByName(this.localTermGroup.Name); } else { this.clientTermGroup = clientTermStore.Groups .GetById(this.localTermGroup.Id); } // TODO: If SyncAction.DeleteExtraChildItems==false, then we can skip this this.ClientContext.Load(this.clientTermGroup, g => g.Id, g => g.Name, // For AssignClientChildItems() // TODO: We can sometimes skip this g => g.TermSets.Include(ts => ts.Id) ); } using (this.exceptionHandlingScope.StartCatch()) { } } return(true); }
protected override bool OnProcessCheckExistence() { this.clientTermSet = null; this.localizedNameQueries = null; TermGroupUploader groupUploader = (TermGroupUploader)this.GetParentUploader(); if (!groupUploader.FoundClientObject) { this.WaitForBlocker(groupUploader); return(false); } Debug.Assert(groupUploader.ClientTermGroup != null); this.SetClientWorkingLanguageToDefault(); using (this.Controller.ClientConnector.WorkingLanguageManager.StartUnmanagedScope(this.ClientTermStore)) { this.exceptionHandlingScope = new ExceptionHandlingScope(this.ClientContext); using (this.exceptionHandlingScope.StartScope()) { using (this.exceptionHandlingScope.StartTry()) { if (this.FindByName) { CsomHelpers.FlushCachedProperties(groupUploader.ClientTermGroup.TermSets); this.clientTermSet = groupUploader.ClientTermGroup.TermSets .GetByName(this.localTermSet.Name); } else { // TODO: If "elsewhere" isn't needed, then we // can get this directly from groupUploader.ClientChildTermSets CsomHelpers.FlushCachedProperties(this.ClientTermStore); this.clientTermSet = this.ClientTermStore .GetTermSet(this.localTermSet.Id); } var conditionalScope = new ConditionalScope(this.ClientContext, () => this.clientTermSet.ServerObjectIsNull.Value, allowAllActions: true); using (conditionalScope.StartScope()) { using (conditionalScope.StartIfFalse()) { // TODO: If SyncAction.DeleteExtraChildItems==false, then we can skip this this.ClientContext.Load(this.clientTermSet, ts => ts.Id, ts => ts.Name, ts => ts.Group.Id, ts => ts.CustomProperties, ts => ts.Stakeholders, // For AssignClientChildItems() // TODO: We can sometimes skip this ts => ts.Terms.Include(t => t.Id) ); this.localizedNameQueries = TermSetLocalizedNameQuery.Load( this.clientTermSet, this.Controller.ClientLcids, this.Controller.DefaultLanguageLcid, this.ClientTermStore, this.Controller.ClientConnector ); } } } using (this.exceptionHandlingScope.StartCatch()) { } } } return(true); }
/// <summary> /// Load the special Microsoft Online Service library (MSOIDCLIL.DLL) that is used /// to authenticate requests for SharePoint Online / Office 365 cloud sites. /// </summary> public static void LoadOnlineServiceLibrary(Action <string> logVerbose = null) { if (CsomHelpers.loadOnlineServiceLibrarySucceeded) { return; } if (logVerbose == null) { logVerbose = (message) => { Debug.WriteLine("LoadOnlineServiceLibrary: " + message); }; } // If the service library DLL's are present in the tool directory, then load the appropriate // version depending on whether the tool is running in 32-bit or 64-bit mode. string[] filenames = new[] { "MSOIDCLIL.DLL", "MSOIDRES.DLL" }; bool first = true; bool failed = false; foreach (string filename in filenames) { if (CsomHelpers.LoadLibrary(filename) == IntPtr.Zero) { string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message; if (first) { failed = true; break; } else { throw new InvalidOperationException("Unable to load library \"" + filename + "\" from OS environment: " + errorMessage + "\r\nFor the latest version, visit " + CsomHelpers.ClientSdkUrl); } } first = false; } if (!failed) { if (logVerbose != null) { logVerbose("Loaded service authentication libraries from OS environment"); } CsomHelpers.loadOnlineServiceLibrarySucceeded = true; return; } Assembly assembly = typeof(CsomHelpers).Assembly; string moduleDllPath = assembly.ManifestModule.FullyQualifiedName; if (!System.IO.File.Exists(moduleDllPath)) { throw new InvalidOperationException("Unable to determine module folder for assembly: " + assembly.FullName); } string moduleDllDirectory = Path.GetDirectoryName(moduleDllPath); string dllFolder = Path.Combine(moduleDllDirectory, IntPtr.Size == 4 ? "Libs32" : "Libs64"); if (!Directory.Exists(dllFolder)) { throw new DirectoryNotFoundException("Unable to load the " + filenames[0] + " library; it was not found in the system path nor the " + Path.GetFileName(moduleDllPath) + " folder." + "\r\nFor the latest version, visit " + CsomHelpers.ClientSdkUrl); } foreach (string filename in filenames) { string dllPath = Path.Combine(dllFolder, filename); if (CsomHelpers.LoadLibrary(dllPath) == IntPtr.Zero) { string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message; throw new InvalidOperationException("Unable to load library \"" + dllPath + "\": " + errorMessage); } } if (logVerbose != null) { logVerbose("Loaded service authentication libraries from \"" + dllFolder + "\""); } CsomHelpers.loadOnlineServiceLibrarySucceeded = true; }
/// <summary> /// Certain CSOM methods cache their return values for the lifetime of the ClientContext. /// (In the server OM, these methods are marked with ClientCallableMethod.CacheReturnValue=true.) /// This can produce incorrect results if the value was changed e.g. by the same session /// that is now trying to read the new value. FlushCachedProperties() can be called in /// this situation to flush the internal cache. It should be called after ExecuteQuery() /// and before the next query expression is loaded. /// </summary> public static void FlushCachedProperties(ClientObject clientObject) { ClientObjectData objectData = CsomHelpers.GetClientObjectData(clientObject); objectData.MethodReturnObjects.Clear(); }
protected override bool OnProcessCheckExistence() { this.clientTerm = null; this.clientTermOtherInstance = null; this.descriptionResultsByLcid = null; this.termLinkSourcePathPartLookups = null; this.termLinkSourcePathExceptionHandlingScope = null; TermContainerUploader parentUploader = (TermContainerUploader)this.GetParentUploader(); if (!parentUploader.FoundClientObject) { this.WaitForBlocker(parentUploader); return(false); } TermSetUploader termSetUploader = this.GetTermSetUploader(); if (!termSetUploader.FoundClientObject) { this.WaitForBlocker(termSetUploader); return(false); } if (this.localTerm.TermKind != LocalTermKind.NormalTerm) { if (!this.LoadClientTermOtherInstanceForTermLink()) { return(false); } } if (this.FindByName) { Debug.Assert(this.localTerm.TermKind == LocalTermKind.NormalTerm || this.localTerm.TermKind == LocalTermKind.TermLinkUsingPath); // TODO: If "elsewhere" isn't needed, then we // can get this directly from parentUploader.ClientChildTerms CsomHelpers.FlushCachedProperties(parentUploader.ClientTermContainer.Terms); this.SetClientWorkingLanguageToDefault(); this.exceptionHandlingScope = new ExceptionHandlingScope(this.ClientContext); using (this.exceptionHandlingScope.StartScope()) { using (this.exceptionHandlingScope.StartTry()) { this.clientTerm = parentUploader.ClientTermContainer.Terms .GetByName(this.localTerm.Name); this.ClientContext.Load(this.clientTerm, t => t.Id, t => t.Name, t => t.IsReused, t => t.IsSourceTerm, t => t.IsPinned, t => t.IsPinnedRoot, t => t.CustomProperties, t => t.LocalCustomProperties, t => t.Labels.Include( label => label.IsDefaultForLanguage, label => label.Language, label => label.Value ), // For AssignClientChildItems() // TODO: We can sometimes skip this t => t.Terms.Include(ct => ct.Id) ); this.descriptionResultsByLcid = new Dictionary <int, ClientResult <string> >(); foreach (int lcid in this.Controller.ClientLcids) { CsomHelpers.FlushCachedProperties(this.clientTerm); ClientResult <string> result = this.clientTerm.GetDescription(lcid); this.descriptionResultsByLcid.Add(lcid, result); } } using (this.exceptionHandlingScope.StartCatch()) { } } } else { Debug.Assert(this.localTerm.TermKind == LocalTermKind.NormalTerm || this.localTerm.TermKind == LocalTermKind.TermLinkUsingId); this.SetClientWorkingLanguageToDefault(); // The term/link is considered "missing" unless it's somewhere in the intended term set, // since otherwise it's ambiguous which instance should be moved/deleted/etc CsomHelpers.FlushCachedProperties(this.ClientTermStore); this.clientTerm = termSetUploader.ClientTermSet.GetTerm(this.localTerm.Id); this.ClientContext.Load(this.clientTerm, t => t.Id, t => t.Name, t => t.IsReused, t => t.IsSourceTerm, t => t.IsPinned, t => t.IsPinnedRoot, t => t.CustomProperties, t => t.LocalCustomProperties, t => t.Labels.Include( label => label.IsDefaultForLanguage, label => label.Language, label => label.Value ), t => t.Parent.Id, // For AssignClientChildItems() // TODO: We can sometimes skip this t => t.Terms.Include(ct => ct.Id) ); // If we didn't find it in this term set, then do an expensive query to find // all other instances. var scope = new ConditionalScope(this.ClientContext, () => this.clientTerm.ServerObjectIsNull.Value, allowAllActions: true); using (scope.StartScope()) { if (this.clientTermOtherInstance == null) { using (scope.StartIfTrue()) { CsomHelpers.FlushCachedProperties(this.ClientTermStore); this.clientTermOtherInstance = this.ClientTermStore .GetTerm(this.localTerm.Id); this.ClientContext.Load(this.clientTermOtherInstance, t => t.Id, t => t.Name, t => t.IsReused, t => t.IsSourceTerm, t => t.IsPinned, t => t.IsPinnedRoot ); } } using (scope.StartIfFalse()) { this.descriptionResultsByLcid = new Dictionary <int, ClientResult <string> >(); foreach (int lcid in this.Controller.ClientLcids) { CsomHelpers.FlushCachedProperties(this.clientTerm); ClientResult <string> result = this.clientTerm.GetDescription(lcid); this.descriptionResultsByLcid.Add(lcid, result); } } } } return(true); }