Search code examples
c#dynamics-crm-2011dynamics-crmdynamics-crm-4dynamics-crm-2013

System.InvalidCastException: Microsoft Dynamics CRM has experienced an error


I'm attempting to use Microsoft Dynamics CRM SDK to update a record programmatically. Unfortunatey, after I pull the record, update the fields, and call the .Update() method on my service proxy I get the following exception:

[System.ServiceModel.FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>]
System.InvalidCastException: Microsoft Dynamics CRM has experienced an error. 
Reference number for administrators or support: #B08B34D9"  
System.ServiceModel.FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>

Since I've never used CRM before, and we have scare resources that currently use it within the company, I don't know how/where to begin investigating the exception, or any idea where it could come from.

The program begins with the following method. This simply queries the data for a matching EIN number. If no records are found then I use a .Create() method. If records are found we update the currently existing item in Dynamics.

    public string UpdateDynamics(AgentTransmission agt)
    {
        ConditionExpression condition = new ConditionExpression();
        condition.AttributeName = "neu_taxid";
        condition.Operator = ConditionOperator.Equal;
        condition.Values.Add("012-3456787");

        ColumnSet columns = new ColumnSet(true);

        QueryExpression query = new QueryExpression();
        query.ColumnSet = columns;
        query.EntityName = "account";
        query.Criteria.AddCondition(condition);

        OrganizationServiceClient client = new OrganizationServiceClient();
        EntityCollection collection = client.RetrieveMultiple(query);

        if (collection.Entities.Count == 0)
        {
            _servicePoxy.Create(CreateAccount(agt));
        }
        else
        {
            foreach (Entity contact in collection.Entities)
            {
                //This throws the exception
                _servicePoxy.Update(CreateAccount(agt, contact.Id));
            }
        }

        return string.Empty;
    }

Below is the method I use to create the Entity object we pass to Dynamics. The data is pulled from an Entity Framework model object and mapped to the appropriate field.

    private Entity CreateAccount(AgentTransmission agt, Guid Id = new Guid())
    {
        _account = new Entity();
        _account.LogicalName = "account";
        _account.Attributes.Add("name", agt.AgencyName);
        _account.Attributes.Add("telephone1", agt.BusinessPhone.Replace("(","").Replace(")", "").Replace("-", ""));
        _account.Attributes.Add("address1_line1", agt.MailingStreet1);
        _account.Attributes.Add("address1_city", agt.MailingCity);
        _account.Attributes.Add("address1_postalcode", agt.MailingZip);
        _account.Attributes.Add("neu_address1stateprovince", LookupStateCode(agt.MailingState));
        _account.Attributes.Add("address1_addresstypecode", new OptionSetValue(1)); //1 for Mailing
        _account.Attributes.Add("neu_channelid", LookupChannelId(agt.Channel));
        _account.Attributes.Add("neu_appointmentstatus", new OptionSetValue(279660000));
        _account.Attributes.Add("customertypecode", LookupCustomerCode(agt.RelationshipType));
        _account.Attributes.Add("neu_taxid", UnobfuscateRef(agt.ReferenceNumber).ToString());

        //If we're doing an update will need the GUID. Only use when Update is needed. 
        if (Id != Guid.Empty)
        {
            _account.Attributes.Add("accountid", Id);
        }

        return _account;
    }

The .Create() method works as it's supposed to, however, so I think that the exception is isolated to the accountid GUID attribute I use for updates.


Solution

  • In your CreateAccount method when you are processing existing entities, try changing this line:

    _account.Attributes.Add("accountid", Id);
    

    to

    _account.Id = Id;
    

    Theoretically, it shouldn't matter but the Id property of the entity instance should always be set for existing records.

    You might also want to consider passing in an account entity (which you call contact in your for loop) instead of the id into CreateAccount as a parameter and then you wouldn't have to explicitly create an account instance in each call and could also remove the logic which tries to assign the id (as the passed in entity would already have it defined).

    For example, your calls would be:

    _servicePoxy.Create(CreateAccount(agt), new Entity("account"));
    

    and

    _servicePoxy.Update(CreateAccount(agt, contact));
    

    And then you could remove these lines from CreateAccount:

    _account = new Entity();
    _account.LogicalName = "account";
    

    and

    if (Id != Guid.Empty)
    {
        _account.Attributes.Add("accountid", Id);
    }
    

    (I would have posted this as more of a comment, but I don't have enough permissions.)