locked
CRM 2011- Plugins code for a Lookup field RRS feed

  • Question

  • I am stuck on this forever and need an expert to help me through.

    Here is the scenario:

    • I have two tables 1) Contact 2) Contact Address
    • For one contact we can have multiple addresses
    • I have created a lookup field in Contact Address table that will point to Contact table
    • I am writing a plugin for Contact address (update event), so on a certain data change i want to update parent Contact Record

    Question:

    In the plugin code i have to read data from that lookup field so i could modify some data in the parent table (i.e. Contact)

    Name of that lookup field is: "new_contactaddressesid"

    In my code as soon as is use that underlined code in the code section below, i get following error "The given key was not present in the dictionary"

    Here is my complete code of Execute function and tracelog: 

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

                tracer.Trace("ENTER: Execute");
                Entity targetEntity = null; 

                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                {
                    tracer.Trace("Within First IF Block");
                    targetEntity = (Entity)context.InputParameters["Target"];

                    if (targetEntity.LogicalName != "new_contactaddress")
                    { return; }
                }
                else { return; }

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

                tracer.Trace("After service object");

                Entity member = service.Retrieve("contact", ((EntityReference)targetEntity["new_contactaddressesid"]).Id,new ColumnSet(true));


                tracer.Trace("After member initialization);
          }

    Trace Log

    ENTER: Execute
    Within First IF Block
    After service object


    As you can see the last trace was not executed "After member initialization"

     

    Question

    • How do i call the parent entity, based on data in child record

    Tuesday, July 19, 2011 1:51 AM

Answers

  • For update event, CRM will only send the fields that have been changed. If new_contactaddressesid field has not been changed in UI, targetEntity.Attributes.Contains("new_contactaddressesid") will return false. In this case, you should use Pre-Image. 
    Daniel Cai | http://danielcai.blogspot.com
    Tuesday, July 19, 2011 3:49 AM
  • Daniel’s recommendation is correct, I guess when a user changes the address, the contact is not changing, and that is why CRM is not giving you new_contactaddressesid attribute in the Attribute collection, you need to check other address fields in the Attribute collection to see whether the user has changed anything. To get the new_contactaddressesid or any other address attribute use pre-image Attribute collection based on the conditional check.


    Thomas
    • Marked as answer by itsgonabeme Tuesday, July 19, 2011 8:33 PM
    Tuesday, July 19, 2011 5:32 AM
  • try contactaddid = ((EntityReference)preMessageImage.Attributes["new_contactaddressesid"]).Id.ToString();


    vishal swami

    If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"

    http://msdynamics4you.blogspot.com
    • Marked as answer by itsgonabeme Tuesday, July 19, 2011 8:33 PM
    Tuesday, July 19, 2011 7:49 AM
  • Based on the information you provided, your code should be

    preMessageImage = (Entity)context.PreEntityImages["new_contactaddress"];

    Alternatively, you can change the image name in the plugin registration tool, which would be better option in this case, I believe.


    Daniel Cai | http://danielcai.blogspot.com
    • Marked as answer by itsgonabeme Tuesday, July 19, 2011 8:22 PM
    Tuesday, July 19, 2011 7:14 PM
  • Thanks Daniel and Thomas for looking into this and providing me your valuable feedback.
    PreImage and PostImage, very interesting concept, i didn't know that.

    I will start my R&D on the PreImage and PostImage subject.

    Please post any links if you have handy, i am looking at following links:

    http://crmconsultancy.wordpress.com/2010/10/25/plugins-in-crm-2011/

    http://deepakexploring.wordpress.com/category/crm-2011/

    Thanks

    • Marked as answer by itsgonabeme Friday, July 29, 2011 2:01 PM
    Tuesday, July 19, 2011 5:48 AM
  • Also when you register an image, you can specify what fields you want to make available to the image. Please make sure to pick the field that you want to access in your plugin code.
    Daniel Cai | http://danielcai.blogspot.com
    • Marked as answer by itsgonabeme Tuesday, July 19, 2011 8:22 PM
    Tuesday, July 19, 2011 6:04 PM

All replies

  • I have found out an appropriate link to this problem http://community.dynamics.com/product/crm/f/117/p/52840/95196.aspx

    Did a code compare and figured out that i was not using the attributes keyword.

    My working code looks like following:

     

                    if (targetEntity.Attributes.Contains("new_contactaddressesid"))
                    {
                        tracer.Trace("Before Testing Parent call");
                        Entity member = service.Retrieve("contact", ((EntityReference)targetEntity.Attributes["new_contactaddressesid"]).Id, new ColumnSet(true));
                        tracer.Trace("After Testing Parent call");

                         // your business logic goes here..

                    }

                    else {

                       tracer.Trace("In Else block");      

                    }

     

    NEW PROBLEM

    I have data in my Lookup field but system is not executing my IF block, instead its going in ELSE block, so this calls if (targetEntity.Attributes.Contains("new_contactaddressesid")) is returning false.

     

    PLEASE HELP!!!!!!!!!!

     


    Tuesday, July 19, 2011 2:08 AM
  • GURUS/EXPERTS need your help on this?
    Tuesday, July 19, 2011 2:45 AM
  • For update event, CRM will only send the fields that have been changed. If new_contactaddressesid field has not been changed in UI, targetEntity.Attributes.Contains("new_contactaddressesid") will return false. In this case, you should use Pre-Image. 
    Daniel Cai | http://danielcai.blogspot.com
    Tuesday, July 19, 2011 3:49 AM
  • Daniel’s recommendation is correct, I guess when a user changes the address, the contact is not changing, and that is why CRM is not giving you new_contactaddressesid attribute in the Attribute collection, you need to check other address fields in the Attribute collection to see whether the user has changed anything. To get the new_contactaddressesid or any other address attribute use pre-image Attribute collection based on the conditional check.


    Thomas
    • Marked as answer by itsgonabeme Tuesday, July 19, 2011 8:33 PM
    Tuesday, July 19, 2011 5:32 AM
  • Thanks Daniel and Thomas for looking into this and providing me your valuable feedback.
    PreImage and PostImage, very interesting concept, i didn't know that.

    I will start my R&D on the PreImage and PostImage subject.

    Please post any links if you have handy, i am looking at following links:

    http://crmconsultancy.wordpress.com/2010/10/25/plugins-in-crm-2011/

    http://deepakexploring.wordpress.com/category/crm-2011/

    Thanks

    • Marked as answer by itsgonabeme Friday, July 29, 2011 2:01 PM
    Tuesday, July 19, 2011 5:48 AM
  • Hi Daniel and Thomas,

     

    For last hour i have continued my quest of experiment on PreImages, i apologize in advance.

    I am very new to CRM and everything so far is first time so i am learning on the fly. Would appreciate if you can suggest what i am doing wrong here:

     

    So for PreImage, i have registered a new image in the Plugin Reg. Tool, after that i have added following block of code, hoping that i will get the new_contactaddressesid

     

                Entity preMessageImage = null;
                string contactaddid;

                if (context.PreEntityImages.Contains("PreImage") && context.PreEntityImages["PreImage"] is Entity)
                {
                    preMessageImage = (Entity)context.PreEntityImages["PreImage"];
                    contactaddid = (String)preMessageImage.Attributes["new_contactaddressesid"];
                }
                else
                {
                    throw new Exception("No Pre Image Entity in Plugin Context for Message");
                }

     

    But instead i am getting following error:

    Unable to cast object of type 'Microsoft.Xrm.Sdk.EntityReference' to type 'System.String'.Detail:
    <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ErrorCode>-2147220956</ErrorCode>
      <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
      <Message>Unexpected exception from plug-in (Execute): TestProject.ContactAddress: System.InvalidCastException: Unable to cast object of type 'Microsoft.Xrm.Sdk.EntityReference' to type 'System.String'.</Message>
      <Timestamp>2011-07-19T06:49:57.4070582Z</Timestamp>
      <InnerFault i:nil="true" />
      <TraceText>

     

    PLEASE HELP!

    Tuesday, July 19, 2011 7:00 AM
  • try contactaddid = ((EntityReference)preMessageImage.Attributes["new_contactaddressesid"]).Id.ToString();


    vishal swami

    If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"

    http://msdynamics4you.blogspot.com
    • Marked as answer by itsgonabeme Tuesday, July 19, 2011 8:33 PM
    Tuesday, July 19, 2011 7:49 AM
  • contactaddid = ((EntityReference)preMessageImage.Attributes["new_contactaddressesid"]).Id.ToString();

    With above line of code i get following error:

     

    System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.Detail:
    <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ErrorCode>-2147220956</ErrorCode>

    Tuesday, July 19, 2011 3:32 PM
  • Did you register the Pre Image?

    When you register a pre image, you will need to specify an image name, which you use to populate preMessageImage variable in your plugin code. If you have done this right, it should work for you.


    Daniel Cai | http://danielcai.blogspot.com
    Tuesday, July 19, 2011 6:02 PM
  • Also when you register an image, you can specify what fields you want to make available to the image. Please make sure to pick the field that you want to access in your plugin code.
    Daniel Cai | http://danielcai.blogspot.com
    • Marked as answer by itsgonabeme Tuesday, July 19, 2011 8:22 PM
    Tuesday, July 19, 2011 6:04 PM
  • Yes i have registered the PreImage in Plugin Registration tool.

    Here is how it looks like:

    Image Type: Check box (PreImage)

    Name: new_contactaddress

    EntityAlias: PreImage

    Attributes: All Attributes

     

    PS: I am also updating the assembly in Plugin Reg. tool after each rebuild in VS

     

    Tuesday, July 19, 2011 7:06 PM
  • Based on the information you provided, your code should be

    preMessageImage = (Entity)context.PreEntityImages["new_contactaddress"];

    Alternatively, you can change the image name in the plugin registration tool, which would be better option in this case, I believe.


    Daniel Cai | http://danielcai.blogspot.com
    • Marked as answer by itsgonabeme Tuesday, July 19, 2011 8:22 PM
    Tuesday, July 19, 2011 7:14 PM
  • FINALLY DONE!!!! Updated the ImageName in Plugin Reg. tool and it is working all good now.

     

    EVERYBODY THANK SO YOU MUCH FOR HELPING ME and GUIDING ME (step by step with this issue!)

    I OWE YOU ALL A big treat...

     

    ITS AN AWESOME FORUM! KUDOS to you ALL...

     

    Tuesday, July 19, 2011 8:22 PM