I would like to update "Last_x0020_Modified" in the SharePoint documentation.
I am unable to update with the error.
"Invalid data is being used to update the list item. The field you are trying to update may be read-only."
Is there a way to update "Last_x0020_Modified"?
using (var context = new ClientContext("URL"))
{
var passWord = new SecureString();
foreach (char c in "pass".ToCharArray())
{
passWord.AppendChar(c);
}
context.Credentials = new SharePointOnlineCredentials("account", passWord);
var documents = context.Web.Lists.GetByTitle("Document");
documents.Fields.GetByInternalNameOrTitle("Last_x0020_Modified").ReadOnlyField = false;
documents.Update();
context.ExecuteQuery();
var query = CamlQuery.CreateAllItemsQuery();
var collListItem = documents.GetItems(query);
context.Load(collListItem,
items => items.Include(
item => item.Id,
item => item.DisplayName,
item => item.ContentType,
item => item["Modified"],
item => item["Last_x0020_Modified"]
));
context.ExecuteQuery();
foreach (var listItem in collListItem.Where(item => item.ContentType.Name == "folder"))
{
listItem["Last_x0020_Modified"] = "2020/09/01T09:00:00";
}
context.ExecuteQuery();
documents.Fields.GetByInternalNameOrTitle("Last_x0020_Modified").ReadOnlyField = true;
documents.Update();
context.ExecuteQuery();
}
Best Regard.
Per my test, I got the same result as yours on my end. Looks like we cannot change the property "Last_x0020_Modified".
Besides, I found the field "Last_x0020_Modified" is a lookup field.
Related
I am instantiating a List, derived from an ObservableCollection:
var paidTrips = PaidTrips
.GroupBy(p => new {p.LicenseHolderID})
.ToList();
Which, through a foreach loop, gives me access to the various distinct values in LicenseHolderID.
foreach (var licenseHolder in paidTrips) {
// accessing the string value of LicenseHolderID
// but no access to the other items
}
What I need help with:
How can I obtain access to the other items in paidTrips, which pertain to LicenseHolderID? (Why: I am creating invoices, one per LicenseHolderID, and I am building the invoice with the data from all the other collection properties).
To give some context, here's the full collection I am working with:
PaidTrips.Add(new PaidTrip {
LicenseHolderID = dr[0].ToString(),
VehicleID = dr[1].ToString(),
Year = dr[2].ToString(),
Month = dr[3].ToString(),
Payment = (decimal)dr[4],
PaymentNet = (decimal)dr[5],
OrderFee = (decimal)dr[6],
PaymentFee = (decimal)dr[7],
TripVATcode = (decimal)dr[8],
LicenseHolderInvoiceID = dr[9].ToString(),
TripFeeNet = (decimal)dr[10],
TripFeeVATcode = (decimal)dr[11],
RidelRegionInvoiceID = dr[12].ToString(),
});
It does depend what your looking to do with the data for each invoice? are you looking to summarise the data within each LicenseHolderID group?
var PaidTrips = new List<PaidTrip>();
var paidTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.ToList();
foreach (var group in paidTrips)
{
var licenseHolderID = group.Key.LicenseHolderID;
//ie here total payment (This sums all payments for this LicenseHolderID)
var totalPayment = group.Sum(x => x.Payment)
// count of payments made (This Counts all Payments greater than 0)
var totalPayments = group.Count(x => x.Payment > 0)
//Use variables in your invoice generation
}
or as above iterate through each group item and access it in singular form.
If I understand you correctly, you want to access each group member's property. To achieve this, you should use nested foreach to traverse each group and access its members.
var PaidTrips = new List<PaidTrip>();
var paidTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.ToList();
foreach (var group in paidTrips)
{
var licenseHolderID = group.Key.LicenseHolderID;
foreach (var paidTrip in group.ToList())
{
Console.WriteLine(paidTrip.TripFeeNet);
}
}
foreach (var licenseHolder in paidTrips) {
// accessing the string value of LicenseHolderID
if (licenseHolder.Key == desiredLicenseHolderID){
foreach (var paidItem in licenseHolder){
paidItem.VehicleID = .......
}
}
}
The .GrouBy() Returns a IGrouping object which contains the Key and the elements grouped by the key. To access the elements of the Key grouping you are after once you iterated through the items and found the one, you can simply iterate through the item as an array.
I am trying to connect to a SharePoint list via C# and loop through until I find an item in the list that has particular features, then I want to save some data that is in that item and copy it to another item. I am getting an Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException error.
//connect to the SharePoint site
ClientContext context = new ClientContext(#"https://website");
List list = context.Web.Lists.GetByTitle("listName");
ListItemCollection items = list.GetItem(CamlQuery.CreateAllItemsQuery());
context.Load(items);
context.ExecuteQuery();
//loop through items
foreach (var listItem in items)
{
string tmp = null;
if (listItem["fieldName"] != null)
// this is where get the error when I reach one that isn't null
{
if (listItem["fieldName"].ToString() == "criteria")
{
tmp = listItem["fieldName"].ToString();
foreach (var listItem2 in items)
{
if (listItem2["criteria2"].ToString() == tmp)
{
listItem2["fieldName"] = tmp;
listItem2.Update();
}
break;
}
break;
}
}
}
Trying to take the value in listItem["fieldname"] and save it, and copy it into listItem2["fieldname"].
Currently, I am getting an error: Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException error.
Try to load the field.
ClientContext context = new ClientContext(#"http://SP13");
List list = context.Web.Lists.GetByTitle("List23");
ListItemCollection items = list.GetItems(CamlQuery.CreateAllItemsQuery());
context.Load(items, item => item.Include(i => i["Title"], i => i["richtext"]));
context.ExecuteQuery();
I have the code below:
using (var context = new ClientContext(URL))
{
context.Credentials = new SharePointOnlineCredentials(username, password);
Web web = context.Web;
context.Load(web.Lists, lists => lists.Include(list => list.Title, list => list.Id));
context.ExecuteQuery();
List SupportList = context.Web.Lists.GetByTitle("Support");
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem newItem = SupportList.AddItem(itemCreateInfo);
foreach (var selector in f.rtxt_select.Text.Split(','))
{
var s = selector.Split('=');
newItem[s[0].Trim()] = m.GetType().GetProperty(s[1].Trim()).GetValue(m, null);
}
newItem.Update();
context.ExecuteQuery();
f.txtMessage.AppendText("Message has been added to Sharepoint List \n ");
f.lbl_successCount.Text = (Convert.ToInt32(f.lbl_successCount.Text) + 1).ToString();
}
Everything works just fine if the username and password is correct. But Is there is a way i can validate if the user has access to the site(SharePoint Online)?
Check Web.GetUserEffectivePermissions method.
I am trying to retrieve all items from a Sharepoint library with CSOM and create a list of it. I am sure it has something to do with the order of the code. The question is how?
ListItemCollection collListItem = oList.GetItems(camlQuery);
var newList = new List<Item>();
var items = oList.GetItems(camlQuery);
context.Load(collListItem);
context.ExecuteQuery();
foreach (var col in items)
{
newList.Add(new Item()
{
ID = Convert.ToInt32(col["ID"]),
});
}
I get the following error:
The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested
You should have loaded the items object not the collListItems thus your code should look following:
ListItemCollection collListItem = oList.GetItems(camlQuery);
var newList = new List<Item>();
var items = oList.GetItems(camlQuery);
context.Load(items);
context.ExecuteQuery();
I have a same problem, then I recalled ExecuteQuery() below foreach loop and that worked for me
ListItemCollection recruitmentItems= Recuitment.GetItems(camlQuery);
cc.Load(recruitmentItems, items => items.Include(
x => x.Id,
x => x["Title"],
x => x["Email"],
x => x["Phone"]
));
cc.ExecuteQuery();
foreach (ListItem item in recruitmentItems)
{
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem newItem = Applicant.AddItem(itemCreateInfo);
newItem["Title"] = item["Title"];
newItem["Email"] = item["Email"];
newItem["PhoneNumber"] = item["Phone"];
newItem.Update();
}
cc.ExecuteQuery();
Currently i'd like to find all groups within the Active Directory where the current user has the right WriteProperty.
The problem is that i can find all groups where the user directly is inserted, but when the user is within a group and that group has write access it won't show up. I thought that setting the booleans of GetAccessRules() would help here, but it doesn't.
So here is the code i already have:
var identity = WindowsIdentity.GetCurrent().User;
var allDomains = Forest.GetCurrentForest().Domains.Cast<Domain>();
var allSearcher = allDomains.Select(domain =>
{
var searcher = new DirectorySearcher(new DirectoryEntry("LDAP://" + domain.Name));
//Apply some filter to focus on only some specfic objects
searcher.Filter = "(&(objectClass=group)(name=*part_of_group_name*))";
return searcher;
});
var itemsFound = allSearcher
.SelectMany(searcher => searcher.FindAll()
.Cast<SearchResult>()
.Select(result => result.GetDirectoryEntry()));
var itemsWithWriteAccess = itemsFound
.Where(entry => entry.ObjectSecurity.GetAccessRules(true, true, typeof(SecurityIdentifier))
.Cast<ActiveDirectoryAccessRule>()
.Where(rule => rule.IdentityReference == identity)
.Where(rule => (rule.ActiveDirectoryRights & ActiveDirectoryRights.WriteProperty) == ActiveDirectoryRights.WriteProperty)
.Count() > 0);
foreach (var item in itemsWithWriteAccess)
{
Debug.Print(item.Name);
}
After a long time and the help of Harvey through this question i finally found a good working solution.
As already explained by Harvey it can be a little difficult to really further understand what you'll get back in entry.Properties["allowedAttributesEffective"].Value. But for normal purposes all you have to check for a write permission is that this field is simply not null.
Here is the sample code:
// (replace "part_of_group_name" with some partial group name existing in your AD)
var groupNameContains = "part_of_group_name";
var identity = WindowsIdentity.GetCurrent().User;
var allDomains = Forest.GetCurrentForest().Domains.Cast<Domain>();
var allSearcher = allDomains.Select(domain =>
{
var searcher = new DirectorySearcher(new DirectoryEntry("LDAP://" + domain.Name));
// Apply some filter to focus on only some specfic objects
searcher.Filter = String.Format("(&(objectClass=group)(name=*{0}*))", groupNameContains);
return searcher;
});
var directoryEntriesFound = allSearcher
.SelectMany(searcher => searcher.FindAll()
.Cast<SearchResult>()
.Select(result => result.GetDirectoryEntry()));
var allowedTo = directoryEntriesFound.Select(entry =>
{
using (entry)
{
entry.RefreshCache(new string[] { "allowedAttributesEffective" });
var rights = entry.Properties["allowedAttributesEffective"].Value == null ? "read only" : "write";
return new { Name = entry.Name, AllowedTo = rights };
}
});
foreach (var item in allowedTo)
{
var message = String.Format("Name = {0}, AllowedTo = {1}", item.Name, item.AllowedTo);
Debug.Print(message);
}