2

I am building a migration tool that is migrating items from an XML schema to SharePoint list fields. Everything is working fine except when it comes to the migration of Created By fields. I need to use the client object model to do this.

So far this is what I have:

using (ClientContext ctx = new ClientContext(url))
{
      List lst = ctx.Web.Lists.GetByTitle("list name");
      Field field = lst.Fields.GetByTitle("Created By");
      field.ReadOnlyField = false; //Allow the field to be modified

      //...Get all list items and store in ListItemCollection named 'col'
      foreach (ListItem item in col)
      {
           item["Author"] = xmlNodeValue; //Take the User form the xml schema and insert into sharepoint's created by field
           item.Update();
           ctx.Credentials = creds;
           ctx.ExecuteQuery();
      }
}

The exception thrown when executing against the server:

Invalid data has been used to update the list item. The field you are trying to update may be read only.

I realize that I probably can't store a string of xmlNodeValue in that field, so how can I achieve this?

Also please keep in mind that the user name pulled from xmlNodeValue may not exist as a claims user.

  • 1. Author field can not be set programmatically using CSOM. Eq. field 'Editor' you can set or another user field you can set too. 2. Code i next post sourceCtx.Web.EnsureUser(val.LookupValue) is bad, because use user display text for find object user. Use sourceCtx.Web.GetUserById(val.LookupId) – Kosikovec Jul 14 '16 at 9:17
3

In order to modify/update the Author field using the client object model, you need to make sure to

  • Load the Source Item
  • Load the User Object with Source Context
  • Ensure the User Object in the Destination Context
  • Insert the User Object in the Destination Item
  • Update the Destination Item

Please find below the pseudo code.

sourceCtx.Load(sourceItem);
sourceCtx.ExecuteQuery();

FieldUserValue val = sourceItem["Author"] as FieldUserValue;

User user = sourceCtx.Web.EnsureUser(val.LookupValue);
sourceCtx.Load(user);
sourceCtx.ExecuteQuery();

newDestItem["Author"] = destinationCtx.Web.EnsureUser(user.LoginName);
newDestItem.Update();

Please let me know if you have any further queries.

Thanks, Dinesh

1

Update Author and Editor at the same time for the first version only or Final file without versions.

if (firstVersion || noVersion)
{
authorUserName = ((FieldUserValue)liSource["Author"]).Email;
User author = contextDest.Web.EnsureUser(authorUserName);

if (author != null)
{
    contextDest.Load(liDest, l => l["Author"], l => l["Editor"], l => l["Created"]);
    contextDest.ExecuteQuery();

    // IMPORTANT: Must be same name to get author updated
    liDest["Editor"] = author;
    liDest["Author"] = author;
    liDest["Created"] = liSource["Created"];
    liDest["Modified"] = liSource["Modified"];
    liDest.UpdateOverwriteVersion();
    contextDest.ExecuteQuery();
}
}
0

Use Web.EnsureUser method to get the User object and then use that to update the Author https://msdn.microsoft.com/EN-US/library/microsoft.sharepoint.client.web.ensureuser.aspx

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.