, because we should use CreateCrmService of IPluginExecutionContext. Now crmsvcutil generates classes derived from Microsoft.Xrm.Sdk.Entity and we can use them in plugins.
Entity class has useful method ToEntity<>. It converts Entity to strongly typed class and back. But you should remember that not every conversion is permitted. In case if Entity is instance of different class that you want to convert to, you will receive runtime error like "Cannot convert entity phonecall to activitypointer".
So, if we register our plugin as post stage plugin for PhoneCall entity on SetStateDynamic message, we can receive our phone call as
PhoneCall call = context.PostEntityImages[IMAGE_NAME].ToEntity<PhoneCall>();
In case if state of phone call is completed we have to iterate through activity parties in call.To property:
if (call.StateCode == PhoneCallState.Completed)
{
ProcessParties(service, call.To);
}
PhoneCall usually has only one recipient. But PhoneCall, Fax, Appointment, Letter and some other entities in CRM are Activities. They both have key named ActivityId and placed in related tables in the CRM database. As appointment could have more than one attendee, as emails could have more then one address in To, phone calls and faxes classes support more that one Activity Party in To property.
crmsvcutil utility generates property To as IEnumerable<ActivityParty>.
/// <summary>
/// Person that is being called.
/// </summary>
[Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("to")]
public System.Collections.Generic.IEnumerable<DataModel.ActivityParty> To
{
get
{
return System.Linq.Enumerable.Cast<YourDataModel.ActivityParty>(this.GetAttributeValue<Microsoft.Xrm.Sdk.EntityCollection>("to").Entities);
}
set
{
this.OnPropertyChanging("To");
this.SetAttributeValue("to", new Microsoft.Xrm.Sdk.EntityCollection(new System.Collections.Generic.List<Microsoft.Xrm.Sdk.Entity>(value)));
this.OnPropertyChanged("To");
}
}
But here I have received first issue with beta version of CRM 2011 SDK. If you want to iterate through To items like
foreach (var party in call.To)
{
ProcessActivityParty(service, party);
}
you will receive error "Unable to cast object of type 'Microsoft.Xrm.Sdk.Entity' to type 'YourDataModel.ActivityParty'". I suppose it is error inside beta version and I hope it will be fixed in production. But for now I had to find solution which allow me to iterate through Activity Parties. And I found them.
I didn't cast context.PostEntityImages[IMAGE_NAME].ToEntity<PhoneCall>() but used late binding to access to "To" property.
Entity activity = context.PostEntityImages[IMAGE_NAME];
foreach (var party in ((EntityCollection)activity.Attributes[CustomEntities.Fax.To]).Entities)
{
ProcessActivityParty(service, party);
}
Actually Attributes[CustomEntities.Fax.To] returns item of EntityCollection class and we are able to use this class to retrieve all activity parties.
At the end function ProcessActivityParty:
private void ProcessActivityParty(IOrganizationService service, Entity party1)
{
ActivityParty party = party1.ToEntity<ActivityParty>();
if (party.PartyId.LogicalName == Contact.EntityLogicalName)
{
Contact theContact = new Contact();
theContact.ContactId = party.PartyId.Id;
theContact.New_LastContact = DateTime.Now;
service.Update(theContact.ToEntity<Entity>());
}
}
And do not forget that CustomEntities.Fax.To class property is generated by tool presented in previous post
Hi,
ReplyDeleteThis is a great article, but i get stuck at the first hurdle :-( my context has no PostEntityImages. I have registerd the plugin to the SetStateDynamicEntity message on the phonecall entity in the post operation, but I still get nothing :-(
Also, how do you get access to the PhoneCallState enumeration. I had to create my own
Cheers
Chris, I think, you have also register image. It's not enough just add step. You should add image in PluginRegistration tool.
ReplyDelete[System.Runtime.Serialization.DataContractAttribute()]
ReplyDelete[System.CodeDom.Compiler.GeneratedCodeAttribute("CrmSvcUtil", "5.0.9688.42")]
public enum PhoneCallState
{
[System.Runtime.Serialization.EnumMemberAttribute()]
Open = 0,
[System.Runtime.Serialization.EnumMemberAttribute()]
Completed = 1,
[System.Runtime.Serialization.EnumMemberAttribute()]
Canceled = 2,
}
this is PhoneCallState. It was generated with crmsvcutil.
Almost five years later and I still ran into this exact issue with the latest CRM 2015 sdk. Why Microsoft, why?
ReplyDeleteThere you can download for free, see the first of these data. nonprofit consultants
ReplyDelete