I'm using C# and CSOM to build an application that creates an event in a SharePoint calendar that I know exists in my O365 subscription. I know O365 is SharePoint 2013, but my application targets SharePoint 2010, so I'm going to have to deal with both versions.
No exceptions are thrown and everything appears to succeed, but the new event does not display in the calendar, even after a page refresh. If I get a collection of items with the same event title, the program-entered event is returned, and appears to contain all the columns set in code.
The CalendarItemCreate function puts data in all the required columns of the calendar. If I search for other calendar items I have hand-entered through the SharePoint calendar, I find them. The only difference I can see between either hand-entered or program-entered events is the "Description" column has ' for the hand-entered events.
Any ideas?
private void CalendarItemCreate(ICalendarItem item) {
using (var context = new ClientContext(_calendarLocation)) {
context.Credentials = _credentials;
var web = context.Web;
var transferScheduleList = web.Lists.GetByTitle(TransferScheduleToken);
var listItemCreationInformation = new ListItemCreationInformation();
var listItem = transferScheduleList.AddItem(listItemCreationInformation);
listItem[TitleToken] = item.EventTitle;
listItem[EventDateToken] = item.EventStartLocal;
listItem[EndDateToken] = item.EventStartLocal.AddMinutes(30);
listItem[DescriptionToken] = string.Empty; //item.EventDescription;
listItem[TransferTypeToken] = item.EventTransferType;
listItem[TransferStatusToken] = item.EventTransferStatus;
listItem[CategoryToken] = "Data Transfer";
listItem[ConfigurationFileLocationToken] = item.ConfigurationFileLocation;
listItem[EventTypeToken] = 0;
listItem[FallDayEventToken] = false;
listItem[FrecurrenceToken] = false;
listItem.Update();
context.ExecuteQuery();
}
The solution was a combination of formatting the dates as strings that SharePoint could understand and data type mismatches in two of my transfer columns. The code below was successful.
using (var context = new ClientContext(_calendarLocation)) {
context.Credentials = _credentials;
var web = context.Web;
var transferScheduleList = web.Lists.GetByTitle(TransferScheduleToken);
var listItemCreationInformation = new ListItemCreationInformation();
var listItem = transferScheduleList.AddItem(listItemCreationInformation);
listItem[TitleToken] = item.EventTitle;
listItem[EventDateToken] = item.EventStartLocal.ToUniversalTime().ToString(#"yyyy-MM-ddTHH:mm:ssZ");
listItem[EndDateToken] = item.EventStartLocal.AddMinutes(30).ToUniversalTime().ToString(#"yyyy-MM-ddTHH:mm:ssZ");
listItem[DescriptionToken] = item.EventDescription;
listItem[TransferTypeToken] = item.EventTransferType.ToString();
listItem[TransferStatusToken] = item.EventTransferStatus.ToString();
listItem[CategoryToken] = "Data Transfer";
listItem[ConfigurationFileLocationToken] = item.ConfigurationFileLocation;
listItem[EventTypeToken] = 0;
listItem[FallDayEventToken] = false;
listItem[FrecurrenceToken] = false;
listItem.Update();
context.ExecuteQuery();
Related
I am trying to get a count of the number of items in a Sharepoint List.
I can obtain counts for lists equal to or less than 200. But each page of results contains 200 items and I cannot figure out how to get the next pages.
int listCount = 0;
Microsoft.Graph.List list = new Microsoft.Graph.List();
var queryOptions = new List<QueryOption>()
{
new QueryOption("select", "id"),
new QueryOption("expand", "columns(select=name),items(expand=fields(select=CustomerName))")
};
GraphServiceClient graphServiceClient = GetAuthenticatedGraphClient(scopes).Result;
list = await graphServiceClient.Sites[$"{siteId}"].Lists[$"{listId}"].Request(queryOptions).GetAsync();
if (list.Items != null)
{
listCount = list.Items.Count;
}
I've read through this
https://learn.microsoft.com/en-us/graph/paging
and this
https://learn.microsoft.com/en-us/graph/sdks/paging?tabs=csharp
However #odata.nextLink isn't in the response, and converting the pageIterator code from messages to lists doesn't return any data at all.
The items object does have a field called NextPageRequest, but it is null.
Does anyone please have some example code on how to obtain more pages of Sharepoint List items after the first page?
I found an answer, with some inspiration from
https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/891
The answer was to request Lists[{}].Items, which retrieves a ListItemsCollectionPage object which contains a count. If that count is 200, then QueryOptions is used in to repeat the request for the next ItemsPage
int listCount = 0;
Microsoft.Graph.IListItemsCollectionPage listItems;
GraphServiceClient graphServiceClient = GetAuthenticatedGraphClient(scopes).Result;
listItems = await graphServiceClient.Sites[$"{siteId}"].Lists[$"{listId}"].Items.Request().GetAsync();
itemCount = listItems.Count();
var nextPage = listItems.NextPageRequest;
while (nextPage != null)
{
listItems = await graphServiceClient.Sites[$"{siteId}"].Lists[$"{listId}"].Items.Request(nextPage.QueryOptions).GetAsync();
itemCount = itemCount + listItems.Count();
nextPage = listItems.NextPageRequest;
}
I am working on SharePoint 2016 CSOM to get list item version history. unfortunately i am not getting the field values. please find the code below.
var file = item.File;
var versionFiles = file.Versions;
var fa = file.ListItemAllFields;
clientContext.Load(fa);
clientContext.Load(file);
clientContext.Load(versionFiles);
clientContext.ExecuteQuery();
if (null != versionFiles)
{
var fileVersion = file.Versions[5];
SP.File oldFile =web.GetFileByServerRelativeUrl("/sites/site/_vti_history/1234/list1/file1.pdf");
var allField = oldFile.ListItemAllFields;
clientContext.Load(allField);
}
You could get version history metadata from Lists.asmx.
Sample code:
var web = clientContext.Web;
List spList = clientContext.Web.Lists.GetByTitle("MyDoc");
var item = spList.GetItemById(43);
clientContext.Load(spList);
clientContext.Load(item);
clientContext.ExecuteQuery();
#region customList
Lists.Lists listService = new Lists.Lists();
listService.Credentials = System.Net.CredentialCache.DefaultCredentials;
listService.Url = siteUrl + "/_vti_bin/lists.asmx";
XmlNode nodeAttachments = listService.GetVersionCollection(spList.Id.ToString(), item.Id.ToString(), "Title");
foreach (System.Xml.XmlNode xNode in nodeAttachments)
{
Console.WriteLine(xNode.Attributes["Title"].Value);
}
In sharePoint 2010, I want to set taxonomy values of a document field. The field can take multiple taxonomy terms.
I am doing it the wrong way because the cast of taxoTerms.Concat(terms) in TermCollection class fails :
TaxonomyField taxoField = file.Item.Fields.GetFieldByInternalName(entry.Key)
as TaxonomyField;
TaxonomySession taxoSession = new TaxonomySession(web.Site);
TermStore store = taxoSession.TermStores[taxoField.SspId];
TermSet termSet = store.GetTermSet(taxoField.TermSetId);
if (taxoField.AllowMultipleValues)
{
string[] taxoValues = entry.Value.Split(';');
TermCollection taxoTerms = termSet.GetTerms(taxoValues[0], true);
for (int j = 1; j < taxoValues.Length; j++)
{
TermCollection terms = termSet.GetTerms(taxoValues[j], true);
if (terms.Count > 0)
{
taxoTerms = (TermCollection)taxoTerms.Concat(terms);
}
}
taxoField.SetFieldValue(file.Item, taxoTerms);
}
Do you know how can I add terms to my TermCollection object so I can save the term values in the field ?
I found my solution. Here it is :
TaxonomyField taxoField =
file.Item.Fields.GetFieldByInternalName(entry.Key) as TaxonomyField;
TaxonomySession taxoSession = new TaxonomySession(web.Site);
TermStore store = taxoSession.TermStores[taxoField.SspId];
TermSet termSet = store.GetTermSet(taxoField.TermSetId);
if (taxoField.AllowMultipleValues)
{
string[] taxoValues = entry.Value.Split(';');
TermCollection terms = termSet.GetAllTerms();
List<string> taxonomyValueList = taxoValues.ToList<string>();
TaxonomyFieldValueCollection fieldValues = new TaxonomyFieldValueCollection(taxoField);
foreach (Term term in terms)
{
if (taxonomyValueList.Contains(term.Name))
{
TaxonomyFieldValue fieldValue = new TaxonomyFieldValue(taxoField);
fieldValue.TermGuid = term.Id.ToString();
fieldValue.Label = term.Name;
fieldValues.Add(fieldValue);
}
}
taxoField.SetFieldValue(file.Item, fieldValues);
}
Hope it helps others.
Here is a sample that could work:
var item = file.Item;
var taxonomyField = item.Fields.GetFieldByInternalName(entry.Key);
var values = new TaxonomyFieldValueCollection(taxonomyField);
values.PopulateFromLabelGuidPairs(entry.Value);
item[entry.Key] = values;
item.Update();
I did not test it on a life system so there can be some additional work, but I hope you get the general idea. The values in the entry.Value string have to contain the | and ; separated list of tags. If the tag does not exist you have to create it and get its id before you save it to the item.
HTH
Vojta
I am trying to display a list of users in a custom webpart using the UserProfileManager. For some reason, I can view the webpart and all profiles are output to the screen (maybe because I am an administrator). But when a standard user logs in, they encounter a 403 page.
I have done some reading up on this and I know its something to do with permissions. This is what I have in my code:
private DataTable GetProfiles()
{
DataTable dtUserProfile = new DataTable();
//...DataTable Columns
SPSecurity.RunWithElevatedPrivileges(delegate()
{
Guid guid = SPContext.Current.Site.ID;
using (SPSite intranet = new SPSite(guid))
{
SPUserToken userToken = intranet.Owner.UserToken;
//Get current intranet context.
SPServiceContext sContext = SPServiceContext.GetContext(intranet);
UserProfileManager profileManager = new UserProfileManager(sContext);
int totalUsers = int.Parse(profileManager.Count.ToString());
Random random = new Random();
for (int i = 0; i < NumberOfUsersToRetrieve(NoOfProfiles, totalUsers); i++)
{
int randNumber = random.Next(1, totalUsers);
DataRow drUserProfile;
UserProfile up = profileManager.GetUserProfile(randNumber);
drUserProfile = dtUserProfile.NewRow();
drUserProfile["DisplayName"] = up.DisplayName;
drUserProfile["FirstName"] = up["FirstName"].Value;
drUserProfile["LastName"] = up["LastName"].Value;
drUserProfile["Department"] = up["Department"].Value;
drUserProfile["ContactNumber"] = up["Office"].Value;
drUserProfile["MySiteUrl"] = up.PublicUrl;
dtUserProfile.Rows.Add(drUserProfile);
}
}
});
return dtUserProfile;
}
My code basically gets a random collection of users depending on the number of users I want to return.
Is it possible to create a SPUserToken for a user that all permissions needed to retrieve the user profiles?
Thanks!
I appreciate this question is old, but I had the exact same problem. To help the original poster and other users, I have altered the code from the original post to the following:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite sc = new SPSite(SPContext.Current.Site.ID);
SPServiceContext context = SPServiceContext.GetContext(sc);
HttpContext currentContext = HttpContext.Current;
HttpContext.Current = null;
UserProfileManager profileManager = new UserProfileManager(context);
IEnumerator profileEnum = profileManager.GetEnumerator();
while (profileEnum.MoveNext())
{
UserProfile up = (UserProfile)profileEnum.Current;
if ((up["FirstName"] != null && up["FirstName"].Value != null && !String.IsNullOrEmpty(up["FirstName"].Value.ToString()))
&& (up.PublicUrl != null && !String.IsNullOrEmpty(up.PublicUrl.ToString())))
{
DataRow drUserProfile;
drUserProfile = dtUserProfile.NewRow();
drUserProfile["DisplayName"] = up.DisplayName;
drUserProfile["FirstName"] = up["FirstName"].Value;
drUserProfile["LastName"] = up["LastName"].Value;
drUserProfile["Department"] = up["Department"].Value;
drUserProfile["Location"] = up["SPS-Location"].Value;
drUserProfile["MySiteUrl"] = up.PublicUrl.ToString().Replace(#"\", #"\");
dtUserProfile.Rows.Add(drUserProfile);
}
}
}
HttpContext.Current = currentContext;
Hopefully this code should resolve the error.
Instead of getting the UserToken of SPSite.Owner, have you tried SPSite.SystemAccount.UserToken, or SPWeb.AllUsers["user"].UserToken;
I'd do the latter if possible, rule of least privileges etc.
I am trying to do a search on a scope in SharePoint. I see this
error.
My code:
using (SPSite siteCollection = new SPSite("http://sp:25000/"))
{
// create a new FullTextSqlQuery class - use property intializers to set query
FullTextSqlQuery query = new FullTextSqlQuery(siteCollection);
query.QueryText = "SELECT Title" + " from scope() where \"scope\" ='ArticleScope'" + "and Contentclass = 'STS_ListItem_GenericList'";
query.ResultTypes = ResultType.RelevantResults;
query.RowLimit = Int32.MaxValue;
query.TrimDuplicates = true;
query.EnableStemming = false;
query.IgnoreAllNoiseQuery = true;
query.KeywordInclusion = KeywordInclusion.AllKeywords;
query.Timeout = 0x2710;
query.HighlightedSentenceCount = 3;
query.SiteContext = new Uri(siteCollection.Url);
// execute the query and load the results into a datatable
ResultTableCollection queryResults = query.Execute();
ResultTable queryResultsTable = queryResults[ResultType.RelevantResults];
DataTable queryDataTable = new DataTable();
queryDataTable.Load(queryResultsTable, LoadOption.OverwriteChanges);
}
Fixed!!!
Used this link
The code I have used:
using (SPSite siteCollection = new SPSite("http://sp:25000/"))
{
Microsoft.Office.Server.Search.Query.FullTextSqlQuery query = new Microsoft.Office.Server.Search.Query.FullTextSqlQuery(siteCollection);
query.QueryText = "SELECT Title from scope() where \"scope\" ='All Sites' and Contentclass = 'STS_ListItem_GenericList'";
query.ResultTypes = Microsoft.Office.Server.Search.Query.ResultType.RelevantResults;
query.RowLimit = Int32.MaxValue;
query.TrimDuplicates = true;
query.EnableStemming = false;
query.IgnoreAllNoiseQuery = true;
query.KeywordInclusion = Microsoft.Office.Server.Search.Query.KeywordInclusion.AllKeywords;
query.Timeout = 0x2710;
query.HighlightedSentenceCount = 3;
query.SiteContext = new Uri(siteCollection.Url);
query.AuthenticationType = Microsoft.Office.Server.Search.Query.QueryAuthenticationType.NtAuthenticatedQuery;
Microsoft.Office.Server.Search.Query.ResultTableCollection queryResults = query.Execute();
Microsoft.Office.Server.Search.Query.ResultTable queryResultsTable = queryResults[Microsoft.Office.Server.Search.Query.ResultType.RelevantResults];
DataTable queryDataTable = new DataTable();
queryDataTable.Load(queryResultsTable, LoadOption.OverwriteChanges);
}
Thanks for your support.
How are you accessing SharePoint? From the screenshot it seems as if you have a Web Page running in a Non-SharePoint IIS Web Application on a SharePoint server, which is not supported (Referencing the Microsoft.SharePoint Assembly from ANY Application running outside SharePoint is officially unsupported, even though some features may run)
What happens if you run this code from within SharePoint (i.e. in a Web Part)?
I can't see the error as it's blocked by my proxy. However my guess is that you should have a space before the and. (Is there any reason why this isn't one long string?)
'ArticleScope'" + "and
^
If not can you please copy and paste the error into your question.
You are missing a space before the and.
THis means
where \"scope\" ='ArticleScope'" + "and Contentclass = 'STS_ListItem_GenericList'
becomes
where \"scope\" ='ArticleScope'and Contentclass = 'STS_ListItem_GenericList'
'ArticleScope' and AND are concatenated: 'ArticleScope'and
Are you using Microsoft SharePoint Server 2007 (MOSS)? Or do you only have Windows SharePoint Services 3.0 (WSS)? From what I saw, Scopes are a MOSS-Feature not available in WSS, but I'm guessing a bit.