Question

I want to write a Dynamics CRM 2011 (online) plugin that takes an address of a contact entity and creates a customeraddress entity from it. It should basically take the customeraddress with address number 1 and create a new identical customeraddress with address number 3 from it. the parent of the newly created customeraddress should be the contact.

I wrote the following plugin to achieve that:

namespace Plugins
{
    using System;
    using System.Linq;
    using System.ServiceModel;
    using Microsoft.Xrm.Sdk;
    using Plugins.Entities;
    using Microsoft.Xrm.Sdk.Query;
    using System.Collections.Generic;

    /// <summary>
    /// AddressMover Plugin.
    /// </summary>    
    public class AddressMoverPlugin : Plugin
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="AddressMoverPlugin"/> class.
        /// </summary>
        public AddressMoverPlugin()
            : base(typeof(AddressMoverPlugin))
        {
            base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(20, "Update", "contact", new Action<LocalPluginContext>(ExecuteAddressMoverPlugin)));
        }

        /// <summary>
        /// Executes the plug-in.
        /// </summary>
        /// <param name="localContext">The <see cref="LocalPluginContext"/> which contains the
        /// <see cref="IPluginExecutionContext"/>,
        /// <see cref="IOrganizationService"/>
        /// and <see cref="ITracingService"/>
        /// </param>
        protected void ExecuteAddressMoverPlugin(LocalPluginContext localContext)
        {
            if (localContext == null)
            {
                throw new ArgumentNullException("localContext");
            }

            //Extract the tracing service for use in debugging sandboxed plug-ins.
            ITracingService tracingService = localContext.TracingService;

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = localContext.PluginExecutionContext;
            IOrganizationService service = localContext.OrganizationService;

            Entity entity = context.InputParameters["Target"] as Entity;
            if(entity.Contains("address1_line1"))
            {
                var newAddress = new Entity("customeraddress");
                newAddress.Attributes["name"] = "business";

                // details about type codes can be found here: http://msdn.microsoft.com/en-us/library/aa682922.aspx
                newAddress.Attributes["objecttypecode"] = 2;
                //newAddress.Attributes["addresstypecode"] = "Other";

                newAddress.Attributes["parentid"] = entity.Id;
                tracingService.Trace("parent id is: " + newAddress["parentid"]);

                newAddress.Attributes["addressnumber"] = 3;
                if (entity.Contains("address1_line1")) newAddress["line1"] = entity["address1_line1"];
                if (entity.Contains("address1_line2")) newAddress["line2"] = entity["address1_line2"];
                if (entity.Contains("address1_line3")) newAddress["line3"] = entity["address1_line3"];
                if (entity.Contains("address1_city")) newAddress["city"] = entity["address1_city"];
                if (entity.Contains("address1_stateorprovince")) newAddress["stateorprovince"] = entity["address1_stateorprovince"];
                if (entity.Contains("address1_postalcode")) newAddress["postalcode"] = entity["address1_postalcode"];
                if (entity.Contains("address1_country")) newAddress["country"] = entity["address1_country"];

                service.Create(newAddress);
                //throw new Exception("Start tracing");
            }
        }
    }
}

Please note the line:

                tracingService.Trace("parent id is: " + newAddress["parentid"]);

When I execute this, I get an error message saying that the parentid is not set:

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Attribute: parentid cannot be set to NULLDetail: 
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ErrorCode>-2147220989</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
  <Message>Attribute: parentid cannot be set to NULL</Message>
  <Timestamp>2013-09-05T10:42:46.0285782Z</Timestamp>
  <InnerFault i:nil="true" />
  <TraceText>
[Plugins: Plugins.AddressMoverPlugin]
[2d6c4656-6815-e311-a90e-ac162dbe3ffe: AddressMoverPlugin]
Entered Plugins.AddressMoverPlugin.Execute(), Correlation Id: 65dc4a08-1075-4340-83a5-d35464375348, Initiating User: 1d55dd88-f2f8-e211-a305-ac162db64ac6
Plugins.AddressMoverPlugin is firing for Entity: contact, Message: Update, Correlation Id: 65dc4a08-1075-4340-83a5-d35464375348, Initiating User: 1d55dd88-f2f8-e211-a305-ac162db64ac6
parent id is: b6eb3f86-1716-e311-aa0d-ac162dbe3218
Exception: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: Attribute: parentid cannot be set to NULL (Fault Detail is equal to Microsoft.Xrm.Sdk.OrganizationServiceFault)., Correlation Id: 65dc4a08-1075-4340-83a5-d35464375348, Initiating User: 1d55dd88-f2f8-e211-a305-ac162db64ac6
Exiting Plugins.AddressMoverPlugin.Execute(), Correlation Id: 65dc4a08-1075-4340-83a5-d35464375348, Initiating User: 1d55dd88-f2f8-e211-a305-ac162db64ac6

</TraceText>
</OrganizationServiceFault>

The trace obviously contains the output from the code that says that the parentid field is set:

parent id is: b6eb3f86-1716-e311-aa0d-ac162dbe3218

Why do I get this error message saying that the parent id is null when it is not? And how can I avoid it? Is this due to the special behaviour of cutomeraddress entities in the Dynamics CRM?

Was it helpful?

Solution

Is parentid is an EntityReference?

If yes, then try as below:

EntityReference parentRef = new EntityReference();
parentRef.Id = entity.Id;
parentRef.EntityLogicalName = "contact";

newAddress.Attributes["parentid"] = parentRef;

I hope it will work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top