sharepoint-clientobject https://www.e-learn.cn/tag/sharepoint-clientobject zh-hans Create CSOM ClientContext with re-usability like singleton pattern https://www.e-learn.cn/topic/3447135 <span>Create CSOM ClientContext with re-usability like singleton pattern</span> <span><span lang="" about="/user/24" typeof="schema:Person" property="schema:name" datatype="">Deadly</span></span> <span>2020-02-29 06:45:04</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><aside class="s-notice s-notice__info js-post-notice mb16" aria-hidden="false" role="status"><div class="grid fd-column fw-nowrap"> <div class="grid fw-nowrap"> <div class="grid--cell mr8"> <svg aria-hidden="true" class="svg-icon iconClock" width="18" height="18" viewbox="0 0 18 18"><path d="M9 17A8 8 0 1 1 9 1a8 8 0 0 1 0 16zm0-2A6 6 0 1 0 9 3a6 6 0 0 0 0 12zM8 5h1.01L9 9.36l3.22 2.1-.6.93L8 10V5z"></path></svg></div> <div class="grid--cell fl1 lh-lg"> <div class="grid--cell fl1 lh-lg"> <b>The bounty expires <span title="2020-03-03 11:25:11Z">in 4 days</span></b>. Answers to this question are eligible for a <span class="s-badge__bounty d-inline px4 py2 ba bc-transparent bar-sm fs-caption va-middle">+50</span> reputation bounty. Amna wants to <b>draw more attention</b> to this question: <blockquote> <div>I need the accurate answer which will highlight how can making a static ClientContext object for reusability can affect? and what is the expiry of this context as when it is required to be refreshed?</div> </blockquote> </div> </div> </div> </div> </aside><p>I have multiple methods being called on different user actions which is using <strong>ClientContext</strong>. Creating it on every method execution was causing performance issue.</p> <p>So I added it as static variable for re-usability, the performance improved with an average of 5seconds but then in some methods it start giving random issue of <strong><em>"Version conflict"</em></strong> on <strong>ExecuteQuery()</strong>. But if I remove the static and null check, then it get refreshed every time and performance becomes an issue</p> <p>Is there any way to create one time object of this or at-least not on every call? And what is the default expiry of ClientContext?</p> <p><strong><em>Code for creating object of ClientContext:</em></strong></p> <pre><code> public class SPConnection { public static ClientContext SharepointClientContext { get; set; } public static ClientContext GetSharePointContext() { try { if (SharepointClientContext == null) { string appId = System.Configuration.ConfigurationManager.AppSettings["appId"]; string appSecret = System.Configuration.ConfigurationManager.AppSettings["appSecret"]; string siteUrl = System.Configuration.ConfigurationManager.AppSettings["siteUrl"]; var authManager = new OfficeDevPnP.Core.AuthenticationManager(); using (ClientContext clientContext = authManager.GetAppOnlyAuthenticatedContext(siteUrl, appId, appSecret)) { SharepointClientContext = clientContext; return clientContext; } } else return SharepointClientContext; } catch (Exception ex) { iChange.Web.API.Authentication.SPConnection.InsertRecordToTableErrorLog("Mucebat:"+ex.Message, ex.StackTrace.ToString()); throw ex; } } </code></pre> <p><strong><em>Code for one of the method consuming it:</em></strong></p> <pre><code> public bool UpdateProfilePic(updateprofilepicmodel model) { using (ClientContext context = SPConnection.GetSharePointContext()) { List list = context.Web.Lists.GetByTitle("Members"); ListItemCreationInformation info = new ListItemCreationInformation(); ListItem item = list.GetItemById(model.MemberId); item["ProfilePicture"] = model.ProfilepicUrl; item.Update(); context.ExecuteQuery(); return true; } } </code></pre> <br /><h3>回答1:</h3><br /><p>Can you try using <code>ExecuteQueryAsync</code> in combination with async tasks for performance improvement? e.g.</p> <pre><code> public async Task &lt;bool&gt; UpdateProfilePic(updateprofilepicmodel model) { using (ClientContext context = SPConnection.GetSharePointContext()) { List list = context.Web.Lists.GetByTitle("Members"); ListItem item = list.GetItemById(model.MemberId); context.Load(item); Task t1 = context.ExecuteQueryAsync(); await t1.ContinueWith((t) =&gt; { item["ProfilePicture"] = model.ProfilepicUrl; item.Update(); Task t2 = context.ExecuteQueryAsync(); }); await t2.ContinueWith((t) =&gt; { // do some stuff here if needed }); return true; } } </code></pre> <p>P.S: i have not tested this code, but in case if this works for you</p> <br /><br /><br /><h3>回答2:</h3><br /><p>You can try to <strong>Load</strong> the list item before update it. Modify the code as below to check if it works.</p> <pre><code>public bool UpdateProfilePic(updateprofilepicmodel model) { using (ClientContext context = SPConnection.GetSharePointContext()) { List list = context.Web.Lists.GetByTitle("Members"); ListItem item = list.GetItemById(model.MemberId); context.Load(item); context.ExecuteQuery(); item["ProfilePicture"] = model.ProfilepicUrl; item.Update(); context.ExecuteQuery(); return true; } } </code></pre> <p>If the code above not works, you can enable the version of the "Members" list in list settings to check if the issue still exists.</p> <br /><br /><br /><h3>回答3:</h3><br /><p>You cannot use ClientContext as static object. In code you are writing your code in Using segment. ClientContext object will destroy once the execution of us using block is completed.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/60353928/create-csom-clientcontext-with-re-usability-like-singleton-pattern</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c" hreflang="zh-hans">c#</a></div> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/csom" hreflang="zh-hans">csom</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> <div class="field--item"><a href="/tag/clientcontext" hreflang="zh-hans">clientcontext</a></div> </div> </div> Fri, 28 Feb 2020 22:45:04 +0000 Deadly 3447135 at https://www.e-learn.cn Namespace 'SharePoint' does not exist in the namespace 'Microsoft' https://www.e-learn.cn/topic/3188653 <span>Namespace &#039;SharePoint&#039; does not exist in the namespace &#039;Microsoft&#039;</span> <span><span lang="" about="/user/96" typeof="schema:Person" property="schema:name" datatype="">自闭症网瘾萝莉.ら</span></span> <span>2020-01-12 07:58:18</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>So I am starting to learn C#, like literally just started learning, and coming from a Java background, it doesn't look too bad. However, I have a question. I am following THIS tutorial on using the client-object model. And just starting from the top, I added the references, but <code>using Microsoft.SharePoint.Client;</code> keeps giving me the error that "the namespace 'SharePoint' does not exist in the namespace 'Microsoft', but I clearly see it on the right side panel. So looking at the instructions, the only difference I can think of is that fact that I am using Visual Studio Express and thus do not have the option to choose which framework to use when creating a new project. Other than that, I don't know what the problem might be. Does anyone have any ideas on what else I could be missing or how to correct this problem?</p> <br /><h3>回答1:</h3><br /><p>Did you add the references to the <code>Microsoft.SharePoint.Client</code> assembly and <code>Microsoft.SharePoint.Client.Runtime</code> assembly as noted near the beginning of that tutorial?</p> <br /><br /><br /><h3>回答2:</h3><br /><p>Make sure that the target framework is 3.5 and not 4 i.e for SP2010</p> <br /><br /><br /><h3>回答3:</h3><br /><ol><li>Add required references to the solution. </li> <li>Make sure that the <strong>target framework is 4 for SP2013</strong>(3.5 for SP2010).</li> </ol><br /><br /><br /><h3>回答4:</h3><br /><p>Did you do this part of the tutorial you mentioned above?</p> <blockquote> <p>To build the application, you must add references to two assemblies, Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll. Installing SharePoint Foundation installs these assemblies on the server. The two assemblies are located in the following directory:</p> <p>%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\ISAPI</p> </blockquote> <br /><br /><br /><h3>回答5:</h3><br /><p>Take a look at the references in your project and make sure you have the reference to the assembly. If it is not there try adding it, right click --&gt;add reference and find "Microsoft.SharePoint.Client"</p> <br /><br /><br /><h3>回答6:</h3><br /><p>Thanks to those who mentioned the 4.0 framework. </p> <p>Mine defaulted to .NET Framework 4 Client Profile (and I have no idea what that means), and the Namespaces looked good in Intellisense, but the build would say they weren't found! Crazy.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/6932617/namespace-sharepoint-does-not-exist-in-the-namespace-microsoft</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c" hreflang="zh-hans">c#</a></div> <div class="field--item"><a href="/tag/net" hreflang="zh-hans">.net</a></div> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/new-operator" hreflang="zh-hans">new-operator</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> </div> </div> Sat, 11 Jan 2020 23:58:18 +0000 自闭症网瘾萝莉.ら 3188653 at https://www.e-learn.cn Programmatically get ListItemVersion using client object model SharePoint 2010 https://www.e-learn.cn/topic/3035613 <span>Programmatically get ListItemVersion using client object model SharePoint 2010</span> <span><span lang="" about="/user/89" typeof="schema:Person" property="schema:name" datatype="">巧了我就是萌</span></span> <span>2020-01-01 05:01:46</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I have a scenario where I have to move all my data in a SharePoint 2010 list (name= "VersionTestList") to a SQL server database. Since versioning is enabled in the list, I want to move the previous version details too. Anyway I was able to move the latest item, but unfortunately I am not able to get the previous version data. I have tried this using Client Object Model and able to get the versions, but not able to get the ListItem of that corresponding version. Please find below the code which I have tried till now and give me a hand in resolving this.</p> <p>Also, I am taking the version of the ListItem like this: </p> <pre><code>string path = web.ServerRelativeUrl + "/Lists/VersionTestTable/1_.000"; File file = web.GetFileByServerRelativeUrl(path); clientContext.Load(file, item=&gt;item.ListItemAllFields); FileVersionCollection versions = file.Versions; clientContext.Load(versions); oldVersions = clientContext.LoadQuery(versions.Where(v =&gt; v != null)); clientContext.ExecuteQuery(); </code></pre> <p>My entire code is like this:</p> <pre><code>class Program { static void Main(string[] args) { GetVersionsUsingCOM(); } public static void GetVersionsUsingCOM() { File file; FileVersionCollection versions; IEnumerable&lt;Microsoft.SharePoint.Client.FileVersion&gt; oldVersions; ClientContext clientContext = new ClientContex("http://server:1200/test/Poc"); Web web = clientContext.Web; clientContext.Load(web); clientContext.ExecuteQuery(); string path = web.ServerRelativeUrl + "/Lists/VersionTestTable/1_.000"; file = web.GetFileByServerRelativeUrl(path); clientContext.Load(file, item=&gt;item.ListItemAllFields); //clientContext.ExecuteQuery(); versions = file.Versions; clientContext.Load(versions); oldVersions = clientContext.LoadQuery(versions.Where(v =&gt; v != null)); clientContext.ExecuteQuery(); if (oldVersions != null) { foreach (Microsoft.SharePoint.Client.FileVersion _version in oldVersions) { int count=0; Console.WriteLine(_version.CheckInComment); Console.WriteLine("Version : {0}", _version.VersionLabel); //// Working fine till here but unable to get the version details from version.Url string versionItemUrl = web.ServerRelativeUrl +"/" + _version.Url; File oldFile = web.GetFileByServerRelativeUrl(versionItemUrl); clientContext.Load(oldFile, f=&gt;f.ListItemAllFields); clientContext.ExecuteQuery(); Console.WriteLine(oldFile.ListItemAllFields["Name"]); count++; } oldVersions = null; } Console.ReadLine(); } } </code></pre> <br /><h3>回答1:</h3><br /><p>You have to initialize <code>web.ServerRelativeUrl</code> like this</p> <pre><code>oldVersions = clientContext.LoadQuery(versions.Where(v =&gt; v != null)); clientContext.Load(web, w =&gt; w.ServerRelativeUrl); clientContext.ExecuteQuery(); </code></pre> <br /><br /><br /><h3>回答2:</h3><br /><p>you can get older version file like this</p> <pre><code>string versionItemUrl = file.ServerRelativeUrl.Replace(Path.GetFileName(file.ServerRelativeUrl),"") + _version.Url;<br />File oldFile = web.GetFileByServerRelativeUrl(versionItemUrl); clientContext.Load(oldFile, f=&gt;f.ListItemAllFields);<br />clientContext.ExecuteQuery();<br /></code></pre> <br /><br /><br /><h3>回答3:</h3><br /><p>You should be able to get the list item data using <code>SPFileVersion.Properties</code> which will give you a hashtable of the file's metedata see MSDN - SPFileVersion.Properties Property.</p> <p>Inside your <code>foreach</code> try</p> <pre><code>Hashtable oHash = oFileVersion.Properties; ICollection collKeys = oHash.Keys; foreach (object oKey in collKeys) { Console.WriteLine(oKey.ToString() + " :: " + oHash[oKey.ToString()].ToString()); } </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/15408687/programmatically-get-listitemversion-using-client-object-model-sharepoint-2010</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/sharepoint-2010" hreflang="zh-hans">sharepoint-2010</a></div> <div class="field--item"><a href="/tag/net-35" hreflang="zh-hans">.net-3.5</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> </div> </div> Tue, 31 Dec 2019 21:01:46 +0000 巧了我就是萌 3035613 at https://www.e-learn.cn Web.GetFileByServerRelativeUrl throws “Value does not fall within expected range” https://www.e-learn.cn/topic/2800263 <span>Web.GetFileByServerRelativeUrl throws “Value does not fall within expected range”</span> <span><span lang="" about="/user/95" typeof="schema:Person" property="schema:name" datatype="">。_饼干妹妹</span></span> <span>2019-12-23 07:03:48</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I have a SP Online site where I store Documents, I have no issues adding/retrieving documents but in the delete flow I get an error during retrieval of a <code>File</code> object.</p> <pre><code>public static void DeleteDocument() { using (ClientContext ctx = ClientContextFactory.Create("https://my-sponline-site.sharepoint.com/sites/documentsite")) { Web web = ctx.Web; ctx.Load(web); ctx.ExecuteQuery(); string relativeUrl = "/Documents/images.jpg"; File file = web.GetFileByServerRelativeUrl(relativeUrl); ctx.Load(file); file.DeleteObject(); ctx.ExecuteQuery(); } } </code></pre> <p>Full Url of the file is "https://my-sponline-site.sharepoint.com/sites/documentsite/Documents/images.jpg" (No more accessible 2016-12-07)</p> <p>When I execute this, I get a <code>ServerException</code> :</p> <blockquote> <p>Value does not fall within the expected range. </p> </blockquote> <p>The Context is working fine as I'm able to add/retrieve items from the library and the context user is <em>administrator</em>.</p> <p>I tried adding the web url to the relativeUrl so it would be "/documentsite/Documents/images.jpg" but I get the same error.</p> <p>I can't seem to figure this out, any suggestions?</p> <p>Thanks</p> <br /><h3>回答1:</h3><br /><pre><code>string relativeUrl = "/sites/documentsite/Documents/images.jpg"; </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/21254703/web-getfilebyserverrelativeurl-throws-value-does-not-fall-within-expected-range</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c" hreflang="zh-hans">c#</a></div> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> <div class="field--item"><a href="/tag/sharepoint-online" hreflang="zh-hans">sharepoint-online</a></div> </div> </div> Sun, 22 Dec 2019 23:03:48 +0000 。_饼干妹妹 2800263 at https://www.e-learn.cn Client-side SharePoint PowerShell - Get list items - The collection has not been initialized https://www.e-learn.cn/topic/2794874 <span>Client-side SharePoint PowerShell - Get list items - The collection has not been initialized</span> <span><span lang="" about="/user/145" typeof="schema:Person" property="schema:name" datatype="">与世无争的帅哥</span></span> <span>2019-12-23 05:14:25</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>On SharePoint 2013, I am trying to get list items, with client-side SharePoint PowerShell. Even for field Id or Title, I encounter this error: The collection has not been initialized. I don't know how to include fields. I find many exemples in C# or JavaScript but none in client side powershell.</p> <p>Here is my code (it returns correctly the number of items):</p> <pre><code>Function New-Context([String]$WebUrl) { $context = New-Object Microsoft.SharePoint.Client.ClientContext($WebUrl) $context.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials $context } Function Get-List([Microsoft.SharePoint.Client.ClientContext]$Context, [String]$ListTitle) { $list = $context.Web.Lists.GetByTitle($ListTitle) $context.Load($list) $context.ExecuteQuery() $list } $context = New-Context -WebUrl "http://mysharepoint.com/sites/qp" $list = Get-List -Context $context -ListTitle "QP-Configuration" $query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery() $items = $list.GetItems($query) $context.Load($items) $context.ExecuteQuery() $items.Count $items[0] foreach($item in $items) { $item.Id } $context.Dispose() </code></pre> <br /><h3>回答1:</h3><br /><p>While getting a specific list item by index at line:</p> <p><code>$items[0]</code></p> <p>or iterating through a collection of <code>Microsoft.SharePoint.Client.ListItemCollection</code>:</p> <pre><code>foreach($item in $items) { #... } </code></pre> <p>every property of object is assumed initialized in PowerShell but this is not the case with <code>Microsoft.SharePoint.Client.ListItem</code> since only a specific subset of properties could be retrieved and this why this error occurs.</p> <p>To retrieve list items values I would suggest to access them via <code>ListItem.FieldValues</code> property:</p> <pre><code>#get list items values $dataValues = @() $items.GetEnumerator() | % { $dataValues += $_.FieldValues } </code></pre> <p><strong>Example</strong></p> <pre><code>$query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery() $items = $list.GetItems($query) $context.Load($items) $context.ExecuteQuery() $dataValues = @() $items.GetEnumerator() | % { $dataValues += $_.FieldValues } $dataValues.Count #determine the amount of items $dataValues[0] #access item by index #iterate through list items and print a specific field value, for example FileRef foreach($item in $dataValues) { $item.FileRef } </code></pre> <br /><br /><br /><h3>回答2:</h3><br /><p>The error was to try to get the full item like that: <code>$items[0]</code> or a column value using <code>$item.Title</code> instead of <code>$item["Title"]</code></p> <p>The correct code is:</p> <pre><code>#Import the required DLL Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll' Function New-Context([String]$WebUrl) { $context = New-Object Microsoft.SharePoint.Client.ClientContext($WebUrl) $context.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials $context } Function Get-List([Microsoft.SharePoint.Client.ClientContext]$Context, [String]$ListTitle) { $list = $context.Web.Lists.GetByTitle($ListTitle) $context.Load($list) $context.ExecuteQuery() $list } $context = New-Context -WebUrl "http://mysharepointsite.com/sites/qp" $list = Get-List -Context $context -ListTitle "QP-Configuration" $query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery() $items = $list.GetItems($query) $context.Load($items) $context.ExecuteQuery() $items.Count foreach($item in $items) { $item["Title"] } $context.Dispose() </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/37788615/client-side-sharepoint-powershell-get-list-items-the-collection-has-not-been</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/powershell" hreflang="zh-hans">powershell</a></div> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/sharepoint-2013" hreflang="zh-hans">sharepoint-2013</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> </div> </div> Sun, 22 Dec 2019 21:14:25 +0000 与世无争的帅哥 2794874 at https://www.e-learn.cn Sharepoint Client Object Model The property or field has not been initialized https://www.e-learn.cn/topic/2791912 <span>Sharepoint Client Object Model The property or field has not been initialized</span> <span><span lang="" about="/user/73" typeof="schema:Person" property="schema:name" datatype="">≡放荡痞女</span></span> <span>2019-12-23 04:41:20</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I have a C# program that manages Sharepoint lists using the Sharepoint Client Object Model. Occasionally we will have server issues which will prevent the program from accessing the sharepoint server. I am using a helper class to run the ExecuteQuery method and have exception handling to continue to execute until there is no exception.</p> <pre><code> private void ExecuteContextQuery(ref ClientContext siteContext) { int timeOut = 10000; int numberOfConnectionErrors = 0; int maxNumberOfRetry = 60; while (numberOfConnectionErrors &lt; maxNumberOfRetry) { try { siteContext.ExecuteQuery(); break; } catch (Exception Ex) { numberOfConnectionErrors++; Service.applicationLog.WriteLine("Unable to connect to the sharepoint site. Retrying in " + timeOut); Service.applicationLog.WriteLine("Exception " + Ex.Message + " " + Ex.StackTrace); System.Threading.Thread.Sleep(timeOut); if (numberOfConnectionErrors == maxNumberOfRetry) { throw Ex; } } } } </code></pre> <p>However I getting an error messages </p> <blockquote> <p>The property or field 'LoginName' has not been initialized. </p> </blockquote> <p>and </p> <blockquote> <p>collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.</p> </blockquote> <p>The error messages seem to be related to methods where I call the Load method. here is an example of my code that calls the method above.</p> <pre><code> List sharepointList = siteContext.Web.Lists.GetByTitle(this._listName); CamlQuery query = CamlQuery.CreateAllItemsQuery(); items = sharepointList.GetItems(query); siteContext.Load(items); //siteContext.ExecuteQuery(); ExecuteContextQuery(ref siteContext); </code></pre> <p>Do I need to reload the site context with every call to ExecuteQuery? Is that why I am seeing the error message above?</p> <p>Here is the function I am using for getting the Login ID which is generating the error</p> <pre><code> public String getLoginIDbyUserId(int userID) { ClientContext siteContext = getClientContextObject(); User _getUser = siteContext.Web.SiteUsers.GetById(userID); siteContext.Load(_getUser); //siteContext.ExecuteQuery(); ExecuteContextQuery(ref siteContext); String loginID = String.Empty; String formatedLoginID = String.Empty; loginID = _getUser.LoginName; if (loginID.Contains('|')) { formatedLoginID = loginID.Substring(loginID.IndexOf('|') + 1); } siteContext.Dispose(); return formatedLoginID; } </code></pre> <br /><h3>回答1:</h3><br /><p>Please try to load <strong>LoginName</strong> property of user while loading user object. And after excutequery method, try to consume <strong>LoginName</strong> property of <strong>User</strong></p> <pre><code>siteContext.Load(_getUser, u =&gt; u.LoginName); </code></pre> <p>And after this change your code should look like this</p> <pre><code>public String getLoginIDbyUserId(int userID) { ClientContext siteContext = getClientContextObject(); User _getUser = siteContext.Web.SiteUsers.GetById(userID); siteContext.Load(_getUser, u =&gt; u.LoginName); //siteContext.ExecuteQuery(); ExecuteContextQuery(ref siteContext); String loginID = String.Empty; String formatedLoginID = String.Empty; loginID = _getUser.LoginName; if (loginID.Contains('|')) { formatedLoginID = loginID.Substring(loginID.IndexOf('|') + 1); } siteContext.Dispose(); return formatedLoginID; } </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/32830230/sharepoint-client-object-model-the-property-or-field-has-not-been-initialized</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c" hreflang="zh-hans">c#</a></div> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> </div> </div> Sun, 22 Dec 2019 20:41:20 +0000 ≡放荡痞女 2791912 at https://www.e-learn.cn Access denied office 365 / SharePoint online with Global Admin account https://www.e-learn.cn/topic/2710093 <span>Access denied office 365 / SharePoint online with Global Admin account</span> <span><span lang="" about="/user/41" typeof="schema:Person" property="schema:name" datatype="">梦想与她</span></span> <span>2019-12-21 05:15:11</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I am going crazy since two days solving an issue. The problem is;</p> <p>I am making a console APP which is talking to SharePoint Online using global admin account (One which was specified as admin while making a new subscription). What I am trying to achieve is, I want to add a custom action using CSOM to each site collection and subsite of office 365. That code works fine except on the root site collection which is pre-created by office 365 while signing up (i.e. https://xyz.sharepoint.com)</p> <p>For any tenant for root site collection, it gives me below error;</p> <blockquote> <p>{ "SchemaVersion":"15.0.0.0","LibraryVersion":"16.0.3912.1201","ErrorInfo":{ "ErrorMessage":"Access denied. You do not have permission to perform this action or access this resource.","ErrorValue":null,"TraceCorrelationId":"2a47fd9c-c07b-1000-cfb7-cdffbe3ab83a","ErrorCode":-2147024891,"ErrorTypeName":"System.UnauthorizedAccessException" },"TraceCorrelationId":"2a47fd9c-c07b-1000-cfb7-cdffbe3ab83a" }</p> </blockquote> <p>Now the user is global admin. I also added again that user as site collection admin. </p> <p>The same piece of code works fine on other site collections (search site collection, any newly made site collection...). </p> <p>here is a code;</p> <pre><code> using (ClientContext spcollContext = new ClientContext(web.Url)) { SecureString passWord = new SecureString(); foreach (char c in strAdminPassword.ToCharArray()) passWord.AppendChar(c); SharePointOnlineCredentials creds = new SharePointOnlineCredentials(strAdminUser, passWord); spcollContext.Credentials = creds; Web currentweb = spcollContext.Web; spcollContext.Load(currentweb); spcollContext.ExecuteQuery(); // authCookie = creds.GetAuthenticationCookie(new Uri(web.Url)); var existingActions2 = currentweb.UserCustomActions; spcollContext.Load(existingActions2); spcollContext.ExecuteQuery(); var actions2 = existingActions2.ToArray(); foreach (var action in actions2) { if (action.Description == "CustomScriptCodeForEachsite" &amp;&amp; action.Location == "ScriptLink") { action.DeleteObject(); spcollContext.ExecuteQuery(); } } var newAction2 = existingActions2.Add(); newAction2.Description = "CustomScriptCodeForEachsite"; newAction2.Location = "ScriptLink"; newAction2.ScriptBlock = scriptBlock; newAction2.Update(); spcollContext.Load(currentweb, s =&gt; s.UserCustomActions); spcollContext.ExecuteQuery(); // GETTING ERROR ON THIS LINE. } </code></pre> <p>Note: Above error is Fiddler traces.</p> <br /><h3>回答1:</h3><br /><p>Most probably this behavior is caused by Custom Script feature, basically the issue occurs when the <em>Custom Script feature</em> is <strong>turned off</strong> </p> <p><strong>How to verify?</strong></p> <p>You could verify the site permissions using the following console app:</p> <pre><code>using (var ctx = GetContext(webUri, userName, password)) { var rootWeb = ctx.Site.RootWeb; ctx.Load(rootWeb, w =&gt; w.EffectiveBasePermissions); ctx.ExecuteQuery(); var permissions = rootWeb.EffectiveBasePermissions; foreach (var permission in Enum.GetValues(typeof(PermissionKind)).Cast&lt;PermissionKind&gt;()) { var permissionName = Enum.GetName(typeof(PermissionKind), permission); var hasPermission = permissions.Has(permission); Console.WriteLine("Permission: {0}, HasPermission: {1}", permissionName, hasPermission); } } </code></pre> <p>where</p> <pre><code>public static ClientContext GetContext(Uri webUri, string userName, string password) { var securePassword = new SecureString(); foreach (var ch in password) securePassword.AppendChar(ch); return new ClientContext(webUri) {Credentials = new SharePointOnlineCredentials(userName, securePassword)}; } </code></pre> <p>When SP.PermissionKind.AddAndCustomizePages is set to <strong>False</strong>, the Access denied error occurs while adding user custom action.</p> <p></p><p></p><p></p><img class="b-lazy" data-src="https://www.eimg.top/images/2020/03/24/9125f8bf9574d6e5af38c5843a9da996.png" data-original="https://www.eimg.top/images/2020/03/24/9125f8bf9574d6e5af38c5843a9da996.png" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" /><p></p><p></p> <p><strong>Solution</strong></p> <p>According to Turn scripting capabilities on or off:</p> <blockquote> <p>For self-service created sites, custom scripting is disabled by default</p> </blockquote> <pre><code>Solution: enable Allow users to run custom scripts on self-service created sites </code></pre> <p>To enable or disable scripting from the SharePoint admin center</p> <ol><li>Sign in to Office 365 with your work or school account.</li> <li>Go to the SharePoint admin center.</li> <li>Select Settings.</li> <li><p>Under Custom Script choose:</p> <ul><li><p>Prevent users from running custom script on personal sites or Allow users to run custom script on personal sites.</p></li> <li><p>Prevent users from running custom script on user created sites or Allow users to run custom script on self-service created sites.</p></li> </ul><p></p><p></p><p></p><img class="b-lazy" data-src="https://www.eimg.top/images/2020/03/24/4190a61bb99790937318d66a1fff5375.png" data-original="https://www.eimg.top/images/2020/03/24/4190a61bb99790937318d66a1fff5375.png" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" /><p></p><p></p></li> <li>Select OK. It takes <strong>about 24 hours</strong> for the change to take effect.</li> </ol><hr /><p>Since any change to the scripting setting made through the SharePoint Online admin center may take up to <strong>24 hours</strong> to take effect, you could enable scripting on a particular site collection <strong>immediately</strong> via CSOM API (SharePoint Online Client Components SDK) as demonstrated below:</p> <pre><code>public static void DisableDenyAddAndCustomizePages(ClientContext ctx, string siteUrl) { var tenant = new Tenant(ctx); var siteProperties = tenant.GetSitePropertiesByUrl(siteUrl, true); ctx.Load(siteProperties); ctx.ExecuteQuery(); siteProperties.DenyAddAndCustomizePages = DenyAddAndCustomizePagesStatus.Disabled; var result = siteProperties.Update(); ctx.Load(result); ctx.ExecuteQuery(); while (!result.IsComplete) { Thread.Sleep(result.PollingInterval); ctx.Load(result); ctx.ExecuteQuery(); } } </code></pre> <p>Usage</p> <pre><code>using (var ctx = GetContext(webUri, userName, password)) { using (var tenantAdminCtx = GetContext(tenantAdminUri, userName, password)) { DisableDenyAddAndCustomizePages(tenantAdminCtx,webUri.ToString()); } RegisterJQueryLibrary(ctx); } </code></pre> <p>where</p> <pre><code>public static void RegisterJQueryLibrary(ClientContext context) { var actions = context.Site.UserCustomActions; var action = actions.Add(); action.Location = "ScriptLink"; action.ScriptSrc = "~SiteCollection/Style Library/Scripts/jQuery/jquery.min.js"; action.Sequence = 1482; action.Update(); context.ExecuteQuery(); } </code></pre> <br /><br /><br /><h3>回答2:</h3><br /><p>If you don't have time for CSOM as described by Vadim, the page also links to a powershell script you can use:</p> <pre><code>Set-SPOsite &lt;SiteURL&gt; -DenyAddAndCustomizePages 0 </code></pre> <p>But note that <code>SiteUrl</code> needs to be the admin url. If your tenant is https://mysite.sharepoint.com, the url you use is https://mysite-admin.sharepoint.com"</p> <p>In our case, we were in the midst of a deployment when this hit and could not wait 24 hours (or even one hour!) to continue. Everything had been fine in our testing site collections, but when we deployed to the tenant root, we hit the error described above and this script fixed it. Apparently the feature is turned off by default on the tenant root.</p> <p>Current site is not a tenant administration site</p> <p>Turn scripting capabilities on or off</p> <br /><br /><br /><h3>回答3:</h3><br /><p>My first response would be that you shouldn't add a <code>CustomAction</code> on the fly through code. That said, I'm sure you have a good reason to need to do so. </p> <p>Try to set the <code>AllowUnsafeUpdates</code> flag on <code>SPWeb</code> to <code>true</code> as soon as you reference <code>currentWeb</code>. Make sure to also set it back to <code>false</code> after you call the final <code>ExecuteQuery()</code></p> <p>By default, <code>AllowUnsafeUpdates</code> is <code>false</code>. It is used to block cross-site scripting attacks. </p> <p>https://msdn.microsoft.com/en-us/library/Microsoft.SharePoint.SPWeb_properties.aspx</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/29675567/access-denied-office-365-sharepoint-online-with-global-admin-account</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/office365" hreflang="zh-hans">office365</a></div> <div class="field--item"><a href="/tag/csom" hreflang="zh-hans">csom</a></div> <div class="field--item"><a href="/tag/sharepoint-online" hreflang="zh-hans">sharepoint-online</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> </div> </div> Fri, 20 Dec 2019 21:15:11 +0000 梦想与她 2710093 at https://www.e-learn.cn How to grant user permission to certain folders using Client Object Model? https://www.e-learn.cn/topic/2631457 <span>How to grant user permission to certain folders using Client Object Model?</span> <span><span lang="" about="/user/190" typeof="schema:Person" property="schema:name" datatype="">邮差的信</span></span> <span>2019-12-19 04:48:10</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>So far I am able to grant user certain permission with the following code:</p> <pre><code> ClientContext context = new ClientContext("http://myRealURL"); Principal user = context.Web.EnsureUser(@"myLoginAccout"); RoleDefinition readDef = context.Web.RoleDefinitions.GetByName("Read"); RoleDefinitionBindingCollection roleDefCollection = new RoleDefinitionBindingCollection(context); roleDefCollection.Add(readDef); RoleAssignment newRoleAssignment = context.Web.RoleAssignments.Add(user, roleDefCollection); context.ExecuteQuery(); </code></pre> <p>The code above works fine, now my task is to add the user permission only to certain folders with C# code. For example, under Libraries, I have a library called <code>JZhu</code>, and inside <code>JZhu</code>, I have two folders <code>folder1</code> and <code>folder2</code>. Is it possible to change the access permission on these two folders with <code>Client Object Model</code>?</p> <p></p><p></p><p></p><img class="b-lazy" data-src="https://www.eimg.top/images/2020/03/23/167d1218cd9994c8eff1b2a3021aa47b.png" data-original="https://www.eimg.top/images/2020/03/23/167d1218cd9994c8eff1b2a3021aa47b.png" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" /><p></p><p></p> <p></p><p></p><p></p><img class="b-lazy" data-src="https://www.eimg.top/images/2020/03/23/9be36c3aff0b2093bcfcb2b7872c4b15.png" data-original="https://www.eimg.top/images/2020/03/23/9be36c3aff0b2093bcfcb2b7872c4b15.png" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" /><p></p><p></p> <br /><h3>回答1:</h3><br /><p>The following example demonstrates how to customize access to folder via CSOM. There are two steps:</p> <ol><li>assign unique permissions for a Folder since by default folder inherits permissions from the parent object (List)</li> <li>grant user permissions to a folder</li> </ol><p>Example:</p> <pre><code>Principal user = ctx.Web.EnsureUser(accountName); var folder = ctx.Web.GetFolderByServerRelativeUrl(folderUrl); var roleDefinition = ctx.Site.RootWeb.RoleDefinitions.GetByType(RoleType.Reader); //get Reader role var roleBindings = new RoleDefinitionBindingCollection(ctx) { roleDefinition }; folder.ListItemAllFields.BreakRoleInheritance(true, false); //set folder unique permissions folder.ListItemAllFields.RoleAssignments.Add(user, roleBindings); ctx.ExecuteQuery(); </code></pre> <p>, where <code>folderUrl</code> parameter corresponds to server relative url for a folder,</p> <p>for example <code>/news/documents/archive</code> for the following structure:</p> <pre><code>News (site) | Documents (library) | Archive (folder) </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/29754692/how-to-grant-user-permission-to-certain-folders-using-client-object-model</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c" hreflang="zh-hans">c#</a></div> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/sharepoint-2010" hreflang="zh-hans">sharepoint-2010</a></div> <div class="field--item"><a href="/tag/permissions" hreflang="zh-hans">permissions</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> </div> </div> Wed, 18 Dec 2019 20:48:10 +0000 邮差的信 2631457 at https://www.e-learn.cn How to grant user permission to certain folders using Client Object Model? https://www.e-learn.cn/topic/2631444 <span>How to grant user permission to certain folders using Client Object Model?</span> <span><span lang="" about="/user/106" typeof="schema:Person" property="schema:name" datatype="">会有一股神秘感。</span></span> <span>2019-12-19 04:47:47</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>So far I am able to grant user certain permission with the following code:</p> <pre><code> ClientContext context = new ClientContext("http://myRealURL"); Principal user = context.Web.EnsureUser(@"myLoginAccout"); RoleDefinition readDef = context.Web.RoleDefinitions.GetByName("Read"); RoleDefinitionBindingCollection roleDefCollection = new RoleDefinitionBindingCollection(context); roleDefCollection.Add(readDef); RoleAssignment newRoleAssignment = context.Web.RoleAssignments.Add(user, roleDefCollection); context.ExecuteQuery(); </code></pre> <p>The code above works fine, now my task is to add the user permission only to certain folders with C# code. For example, under Libraries, I have a library called <code>JZhu</code>, and inside <code>JZhu</code>, I have two folders <code>folder1</code> and <code>folder2</code>. Is it possible to change the access permission on these two folders with <code>Client Object Model</code>?</p> <p></p><p></p><p></p><img class="b-lazy" data-src="https://www.eimg.top/images/2020/03/23/bd251ace6db9baba294f2d467be7800d.png" data-original="https://www.eimg.top/images/2020/03/23/bd251ace6db9baba294f2d467be7800d.png" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" /><p></p><p></p> <p></p><p></p><p></p><img class="b-lazy" data-src="https://www.eimg.top/images/2020/03/23/d40613a82f4eb1507b0478d48f2e8f21.png" data-original="https://www.eimg.top/images/2020/03/23/d40613a82f4eb1507b0478d48f2e8f21.png" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" /><p></p><p></p> <br /><h3>回答1:</h3><br /><p>The following example demonstrates how to customize access to folder via CSOM. There are two steps:</p> <ol><li>assign unique permissions for a Folder since by default folder inherits permissions from the parent object (List)</li> <li>grant user permissions to a folder</li> </ol><p>Example:</p> <pre><code>Principal user = ctx.Web.EnsureUser(accountName); var folder = ctx.Web.GetFolderByServerRelativeUrl(folderUrl); var roleDefinition = ctx.Site.RootWeb.RoleDefinitions.GetByType(RoleType.Reader); //get Reader role var roleBindings = new RoleDefinitionBindingCollection(ctx) { roleDefinition }; folder.ListItemAllFields.BreakRoleInheritance(true, false); //set folder unique permissions folder.ListItemAllFields.RoleAssignments.Add(user, roleBindings); ctx.ExecuteQuery(); </code></pre> <p>, where <code>folderUrl</code> parameter corresponds to server relative url for a folder,</p> <p>for example <code>/news/documents/archive</code> for the following structure:</p> <pre><code>News (site) | Documents (library) | Archive (folder) </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/29754692/how-to-grant-user-permission-to-certain-folders-using-client-object-model</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c" hreflang="zh-hans">c#</a></div> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/sharepoint-2010" hreflang="zh-hans">sharepoint-2010</a></div> <div class="field--item"><a href="/tag/permissions" hreflang="zh-hans">permissions</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> </div> </div> Wed, 18 Dec 2019 20:47:47 +0000 会有一股神秘感。 2631444 at https://www.e-learn.cn SharePoint Foundation 2010 Client Object Model Authentication https://www.e-learn.cn/topic/2476468 <span>SharePoint Foundation 2010 Client Object Model Authentication</span> <span><span lang="" about="/user/162" typeof="schema:Person" property="schema:name" datatype="">冷暖自知</span></span> <span>2019-12-13 14:33:20</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I want to implement a custom logging by passing authentication information, as shown in below reference links:</p> <ul><li>http://blogs.msdn.com/b/cjohnson/archive/2011/05/03/authentication-with-sharepoint-online-and-the-client-side-object-model.aspx</li> <li>http://msdn.microsoft.com/en-us/library/hh147177(v=office.14).aspx</li> </ul><p>I'm using below code but it does not automatically login instead it just popup the login window to enter username and password. I want to automatically log in by passing the credentials pro grammatically.</p> <pre><code>using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.SharePoint.Client; using System.Net; using MSDN.Samples.ClaimsAuth; namespace Sp_Ctx { class Program { [STAThread] static void Main(string[] args) { //if (args.Length &lt; 1) { Console.WriteLine("SP_Ctx &lt;url&gt;"); return; } string targetSite = "https://mysite.sharepoint.com";//args[0]; using (ClientContext ctx = ClaimClientContext.GetAuthenticatedContext(targetSite)) { if (ctx != null) { ctx.Credentials = new NetworkCredential("guest@mysite.com.au", "password", "mysite.sharepoint.com"); ctx.Load(ctx.Web); // Query for Web ctx.ExecuteQuery(); // Execute Console.WriteLine(ctx.Web.Title); } } Console.ReadLine(); } } } </code></pre> <p><strong>UPDATE:</strong></p> <p>I've hosted a <strong>MS 365 sharepoint 2013 site</strong> but i want to use the version 2010 authentication mechanism. </p> <br /><h3>回答1:</h3><br /><p>The MSDN sample project that you're using will only allow claims-based authentication via a pop-up. To do this programmatically, I used a different helper library, Wictor Wilén's claims demo. You can then use his MsOnlineClaimsHelper class to authenticate. Here is sample code taken directly from Wictor's blog: </p> <pre><code>MsOnlineClaimsHelper claimsHelper = new MsOnlineClaimsHelper(url, username, password); using (ClientContext context = new ClientContext(url)) { context.ExecutingWebRequest += claimsHelper.clientContext_ExecutingWebRequest; context.Load(context.Web); context.ExecuteQuery(); Console.WriteLine("Name of the web is: " + context.Web.Title); } </code></pre> <p>This was what I did for a project six months ago. However, I would be interested to hear if there is a new best practice or something provided by Microsoft.</p> <br /><br /><br /><h3>回答2:</h3><br /><p>Try this:</p> <pre><code>ctx.Credentials = new NetworkCredential("guest", "password", "mysite.com.au"); </code></pre> <p>The Domain in the credentials should be the domain of your guest account instead of sharepoint server name.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/15737059/sharepoint-foundation-2010-client-object-model-authentication</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/aspnet" hreflang="zh-hans">ASP.NET</a></div> <div class="field--item"><a href="/tag/sharepoint" hreflang="zh-hans">sharepoint</a></div> <div class="field--item"><a href="/tag/office365" hreflang="zh-hans">office365</a></div> <div class="field--item"><a href="/tag/sharepoint-clientobject" hreflang="zh-hans">sharepoint-clientobject</a></div> </div> </div> Fri, 13 Dec 2019 06:33:20 +0000 冷暖自知 2476468 at https://www.e-learn.cn