4

I am copying items from one list to another using CSOM. Below is my code

foreach (ListItem item in listItems)
{
    ListItemCreationInformation newItemInfo = new ListItemCreationInformation();
    ListItem newItem = listTo.AddItem(newItemInfo);
    newItem["Department"] = item["Department"];
    newItem["Supervisor"] = item["Supervisor"];
    newItem["Employee"] = item["Employee"];
    newItem.Update();
    dctx.ExecuteQuery();
}

Here, Department is a single line of text and it works fine. But supervisor and Employee are person or group fields, and they don't copy correctly.

I also tried

var supervisor = new FieldUserValue { LookupId = ((Microsoft.SharePoint.Client.FieldLookupValue)(item["Supervisor"])).LookupId };
newItem["Supervisor"] = supervisor;

This also didn't work as the lookupID is different in the source list's site and destination list's site.

What should I do?

  • Person and group fields are generally works as lookup column. Try to pass their id. – Dikesh Gandhi Nov 21 '16 at 10:46
  • like newitem["Employee"].LookupId = item["Employee"].LookupId ? – Vignesh Subramanian Nov 21 '16 at 10:48
  • @DikeshGandhi its assigning lookupid correctly, but the problem is due to the difference in lookupid across source and destination site – Vignesh Subramanian Nov 21 '16 at 11:10
  • One workaround is that, just try to find the new id of the user/group in new site using it's login name and pass it in your code. – Dikesh Gandhi Nov 21 '16 at 12:05
5

Use FieldUserValue.LookupValue to get the login name for the selected user, then use Web.EnsureUser() to get the user's ID for the destination site.

foreach (var item in listItems)
{
    var supervisor = destCtx.Web.EnsureUser(((FieldUserValue)item["Supervisor"]).LookupValue);
    var employee = destCtx.Web.EnsureUser(((FieldUserValue)item["Employee"]).LookupValue);
    destCtx.Load(supervisor, user => user.Id);
    destCtx.Load(employee, user => user.Id);
    destCtx.ExecuteQuery();
    var newItem = destList.AddItem( new ListItemCreationInformation() );
    newItem["Supervisor"] = new FieldUserValue { LookupId = supervisorUser.Id };
    newItem["Employee"] = new FieldUserValue { LookupId = employeeUser.Id };
    newItem.Update();
    destCtx.ExecuteQuery();
}

Groups are going to be a tough one, since there's no group equivalent to EnsureUser(). You'll have to get the group name, then query the destination site's groups for the same group.

foreach (var item in listItems)
{
    var departmentId = ((FieldUservalue)item["Department"]).LookupId
    var deparmentGroup = sourceCtx.Web.SiteGroups.GetById(departmentId);
    sourceCtx.Load(departmentGroup, group => group.Title);
    sourceCtx.ExecuteQuery();
    var destGroup = destCtx.Web.SiteGroups.GetByName(departmentGroup.Title);
    destCtx.Load(destGroup, group => group.Id);
    destCtx.ExecuteQuery();
    var newItem = destList.AddItem( new ListItemCreationInformation() );
    newItem["Department"] = new FieldUserValue { LookupId = destGroup.Id };
    newItem.Update();
    destCtx.ExecuteQuery();
}

Combine the two, and you should be good. You may also be able to rewrite it so you're not querying the site as often.

Edit

I need to learn to read. I just saw what you said about the Department field being a string value. I thought it was a people picker as well. The second half of my answer doesn't help you, but maybe it'll be of help to someone else.

3

You need to the read the value of the people field from the source site collection and then add it to the destination.

Try the below sample code. You will need to modify it as per your column names and use it in the loop. In the below code, I am reading the user column value and getting the user object. After I get the User object, I am getting its ID and updating it according to that present in destination site collection:

ClientContext ctx = new ClientContext(siteUrl);

// Create web object
Web web = ctx.Web;
ctx.Load(web);

// Get source list
List list = ctx.Web.Lists.GetByTitle("Source");
ctx.Load(list);

// Get list item using Id e.g. updating first item in the list
ListItem sourceListItem = list.GetItemById(1);

// Load only the assigned to field from the list item
ctx.Load(sourceListItem,item => item["Supervisor"]);  // Use your custom people field
ctx.ExecuteQuery();

// Create and cast the FieldUserValue from the value
FieldUserValue fuv = (FieldUserValue)sourceListItem["Supervisor"]; // Use your custom people field

User user = ctx.Web.EnsureUser(fuv.LookupValue);
ctx.Load(user);
ctx.ExecuteQuery();


FieldUserValue userValue = new FieldUserValue();
userValue.LookupId = user.Id;

// Get the destination list
List destList = communitySite.Lists.GetByTitle("Destination");
Microsoft.SharePoint.Client.ListItem item = destList.AddItem(new ListItemCreationInformation());
item["Supervisor"] = userValue;  // Update the destination people field
item.Update();
clientContext.ExecuteQuery();
1
foreach (ListItem item in listItems)
{
    ListItemCreationInformation newItemInfo = new ListItemCreationInformation();
    ListItem newItem = listTo.AddItem(newItemInfo);
    FieldUserValue s_user= (FieldUserValue)targetListItem["Supervisor"];
    FieldUserValue e_user = (FieldUserValue)targetListItem["Employee"];
    newItem["Department"] = item["Department"];
    newItem["Supervisor"] = s_user.LookupId;
    newItem["Employee"] = e_user.LookupId;
    newItem.Update();
    dctx.ExecuteQuery();
}
  • Thanks, but its across site collection, so the lookupid is returning different users. Will this work in that case? – Vignesh Subramanian Nov 21 '16 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.