Monday, 30 June 2014

CRM 2011/ 2013 Modify CreatedOn, CreatedBy, ModifiedOn, and ModifiedBy Using SDK C#

Often, we have requirements to import data from external data source to CRM and to keep the history, we should keep on eye for these following fields:

1. CreatedOn
2. CreatedBy,
3. ModifiedOn,
4. ModifiedBy

And we often think to update the database directly, yes, it is actually possible.

But, beside it is unsupported way, it is only applicable for those who implement CRM OnPremise, but in fact, we also have another CRM Online.

So, to update those fields using SDK, you can use these code lines:

TargetEntity["createdon"] = new DateTime(2011, 8, 8);
TargetEntity["overriddencreatedon"] = new DateTime(2011, 8, 8);
TargetEntity["createdby"] = new EntityReference("systemuser", new Guid("DDF26A49-4CBA-E311-9400-001CC4EECDD6"));
TargetEntity["modifiedby"] = new EntityReference("systemuser", new Guid("F1F26A49-4CBA-E311-9400-001CC4EECDD6"));
TargetEntity["modifiedon"] = new DateTime(2012, 8, 8);

Do not forget to change to your dynamic values for those assigned field values.

*You should use Late Bound since you cannot use Early Bound:

SNAGHTML1427c435

It will give error says “it is read only”;
And here is the result:

image

 image

Hope it helps!

18 comments:

  1. Hi

    Do you have a sample project for this code, I have been trying to do this with Dynamics CRM Online and I am having no success. I have tried a console app, a custom workflow (no success) and a plugin (seems to work for a single record, but isn't working for a bulk import).

    If you have any guidance I would be really grateful.

    ReplyDelete
  2. Hi Jonathan,

    I've tried using the plugin and console apps.
    You are trying to create custom import?

    ReplyDelete
  3. Could you please supply more sample code, I do not fully understand how to do this from reading this blog post. I've tried to update "modified on" field by doing the entity.attributes["modifiedon"] = __ method, but this does not work. And looking around online, this is about the only place on the entire world wide web that says this is not impossible to do via API , therefore I feel you should supply some more information when you say this can be done.

    ReplyDelete
    Replies
    1. HI Simon,

      Yes, basically many websites said it is not possible, and if I use Early Bound it is also not possible.
      I used the code inside a plugin and it worked after I tried the impossible.
      Thx.

      Delete
  4. I'v tried to do this in a console app.
    "createdon" is overridden by the current datetime. The "overriddencreatedon" stores the date in the "createdon". That's what I want.
    But... "createdby" and/or "createdonbehalfby" cannot be set. The values are overridden by the logged in user.

    ReplyDelete
    Replies
    1. I guess you need a plugin to override it back again, like what I did.
      createdonbehalfby I haven't tried.

      Thanks.

      Delete
  5. Hi Aileen... I can't update createdby field with you istructions! :-(

    ReplyDelete
  6. Marco,

    I tried using plugin and it worked, captured in the picture..
    Now for other apps, to be honest I am becoming unsure, need to try again, thanks Marco for the comment.:)

    ReplyDelete
  7. Aileen Nice Blog!! Same thing I'm doing in CRM2015 online version by C# but it's only updating Created on Field but Created by and Modify by is not updating.

    Can you tell me in CRM2015 it will work???

    ReplyDelete
  8. Wow! Great post! The content is very rich, and I really like it. It help me very much to solve some problems. It is very helpful for all the people on the web. Thanks a lot. Ecommerce Product Photography || Ecommerce Product Photoshoot || Products Catalogue

    ReplyDelete
  9. Wow! Great post! The content is very rich, and I really like it. It help me very much to solve some problems. It is very helpful for all the people on the web. Thanks a lot. Ecommerce Product Photography || Ecommerce Product Photoshoot || Products Catalogue

    ReplyDelete
    Replies
    1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru ASP.NET Essential Training Online . Nowadays Dot Net has tons of job opportunities on various vertical industry.
      or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

      Delete
  10. I have just tested it against CRM 2015 On-line spring release and it worked fine. The trick here is that you MUST register the plug-in step on Pre-Operation execution and just update the incoming target entity in the plug-in context. You don't need to use service.update as well as it is in Pre-Operation it will be updated at the end of the execution pipeline. The code is as below:
    Hope that help.

    public void Execute(IServiceProvider serviceProvider)
    {
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

    var service = factory.CreateOrganizationService(context.UserId);

    // The InputParameters collection contains all the data passed in the message request.
    if (context.InputParameters.Contains("Target") &&
    context.InputParameters["Target"] is Entity)
    {
    // Obtain the target entity from the input parameters.
    Entity entity = (Entity)context.InputParameters["Target"];
    entity["modifiedon"] = new DateTime(2013, 8, 8);
    }

    }

    ReplyDelete
  11. I too can confirm this solution does work if you want the status to remain a default status for the activity. However if you attempt to set the status during data migration it 1) Creates the record 2) Updates the status of the record. Unfortunately, during this second stage, it updates the Modified On and Modified By to be the time of the import and which ever user you chose to import the data as. To get around this you need to first create a flag in your CRM entity and each import record (default to false). Then cut an additional plugin message step for the Update:

    if (preImageEntity.Contains("csp_ismigrationcomplete") && (bool)preImageEntity["csp_ismigrationcomplete"] == false && preImageEntity.Contains("csp_sugarmodifiedon"))
    {
    localContext.TracingService.Trace("PrePhonecallUpdate: Setting the Modified On Date equal to the Sugar Modified On Date.");

    targetEntity["modifiedon"] = (DateTime)preImageEntity["csp_sugarmodifiedon"];
    targetEntity["csp_ismigrationcomplete"] = false; //ensure we set it only once
    }

    I am not sure if you need both Create and Update but possibly records with efult status may not fire the update. You'd certainly need it for any records that didn't have a status set during import.

    All a bit clunky but does the job.

    ReplyDelete
  12. Thanks Aileen, helped me today for CRM 2015 migration.

    ReplyDelete
  13. Thanks! Above code works for CRM 2016 online.

    ReplyDelete
  14. Thanks Aileen!! Above code works for Dynamics 365 online.

    ReplyDelete
  15. Hi there,

    I have inserted several notes but their createdon date are the date i ran the program.

    I know i could borrow overridencreatedon to keep historical date.

    Does overridencreatedon could only be updated on record create?

    Thanks
    Randy

    ReplyDelete

My Name is..