Using context.InputParameters["Target"] - dynamics-crm-2011

I am creating a plugin for Dynamics CRM 2011 to be executed when Qualifying a lead. I use this code
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(null);
Entity curEntity = (Entity)context.InputParameters["Target"];
but when I get the context.InputParameters["Target"] it says that key not found. How can I get the lead entity when qualifying a Lead?

If your plugin is executed on QualifyLead message (Lead as primary entity) you can get the reference to the lead in this way:
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
if (context.InputParameters.Contains("LeadId") && context.InputParameters["LeadId"] is EntityReference)
{
EntityReference leadReference = (EntityReference)context.InputParameters["LeadId"];
Guid leadId = leadReference.Id;
// rest of your code
basically this message doesn't contain Target parameter, instead it contains LeadId parameter.

I needed the name of the entity precisely because my same custom workflow was getting triggered on workflow for two different entities. Thus identifying the Target was necessary until i found "PrimaryEntityName".
context.PrimaryEntityName could be used in case someone is looking to identify which target entity the workflow was triggered on

Related

Automatically trigger a workflow when a record is opened

Is there any way to automatically trigger a Custom Workflow Activity every time any Entity's record is opened?
Sure, you could use the ExecuteWorkflow request from some JavaScript that runs on Form Load. Here's an example of calling ExecuteWorkflow from JavaScript.
http://www.mscrmconsultant.com/2013/03/execute-workflow-using-javascript-in.html
If you're wanting to trigger a custom workflow activity, and don't need to do anything workflow related in it, I'd recommend creating a custom action. It is very similar to a workflow, but CRM will create a custom end point for you to call. It eliminates the need to keep track of workflow IDs...
You can use a Plugin instead of Custom Workflow, and register it on the "Retrieve" message.
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the execution context from the service provider.
Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));
if (context.Depth == 1)
{
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
// Obtain the target entity from the input parmameters.
EntityReference entity = (EntityReference)context.InputParameters["Target"];
ColumnSet cols = new ColumnSet(
new String[] { "lastname", "firstname", "address1_name" });
var contact = service.Retrieve("contact", entity.Id, cols);
if (contact != null)
{
if (contact.Attributes.Contains("address1_name") == false)
{
Random rndgen = new Random();
contact.Attributes.Add("address1_name", "first time value: " + rndgen.Next().ToString());
}
else
{
contact["address1_name"] = "i already exist";
}
service.Update(contact);
}
}
}
CRM 2011–Retrieve Plugin

Dynamics CRM 2011 getting entity has not been modified in post update

I want to get the not modified entity when PostUpdate event triggered.
I try to use
context.PreEntityImages
but it is null.
How to I get this entity in PostUpdate event?
First, you need to register a pre-entityimage for the post-update step.
You can then acquire the entityimage using the following code snippet:
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext) serviceProvider.GetService(typeof (IPluginExecutionContext));
Entity preImage = context.PreEntityImages.First().Value;
}

CRM 2011 Update System User when New account created

I am trying to populate a field in the system user entity whenever a user creates an account. I keep getting errors when trying to retrieve the system user entity so that I can populate its attributes. My code is as follows:
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingservice = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.InitiatingUserId);
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
try
{
//Get entity that fired plugin
Entity entMain = (Entity)context.InputParameters["Target"];
//Make a String for the last activity entity
String strLastEntity = "";
//Make the entity for the user entity
Entity entUser = (Entity)service.Retrieve("systemuser", context.InitiatingUserId, new ColumnSet(new String[] { "new_lastactivityentity" }));
//Get the entity type that fired the plugin and set it to the right field for the user entity
if (entMain.LogicalName.Equals("account"))
{
strLastEntity = entMain.LogicalName;
entUser["new_lastactivityentity"] = strLastEntity;
}
}
catch (Exception ex)
{
tracingservice.Trace("FollowupPlugin: {0}", ex.ToString());
throw;
}
}
}
The error is:
Could not load file or assembly 'PluginRegistration, Version=2.1.0.1, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Can someone explain how to get the system user so I can update its attributes?
It is because you have an assembly reference that isn't installed on the server, in particular that is PluginRegistration.
You could place that dll in the GAC on the server, however this won't work for CRM Online (or in a Sandbox registration I believe).
Is PluginRegistration a reference to the Microsoft assembly used in the plugin registration tool? Generally speaking you don't need a reference to that in your project, so you could try removing the reference.

Cannot create a contact in CRM 2011 Online using a plug-in

Below is the code I am using to create a contact in CRM 2011 online. It's not throwing any error but it also not creating any contact. I have registered the plugin on Post-Operation create event of the e-mail entity. I don't know if I am missing something. Any help would be appreciate.
public class RegistrationPlugin : IPlugin
{
private OrganizationServiceContext oContext;
public void Execute(IServiceProvider serviceProvider)
{
Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
oContext = new OrganizationServiceContext(service);
//service.EnableProxyTypes();
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
try
{
Entity entity = (Entity)context.InputParameters["Target"];
if (entity.LogicalName == "email")
{
Guid _contactId;
var contact = new Contact()
{
FirstName = "Mary Kay",
LastName = "Andersen",
Address1_Line1 = "23 Market St.",
Address1_City = "Sammamish",
Address1_StateOrProvince = "MT",
Address1_PostalCode = "99999",
Telephone1 = "12345678",
EMailAddress1 = "marykay#contoso.com",
Id = Guid.NewGuid()
};
_contactId = contact.Id;
oContext.AddObject(contact);
}
}
catch (Exception x)
{
throw new Exception(x.ToString() + "\n" + x.InnerException.ToString());
}
}
}
}
I can see that you're missing one statement which is:
oContext.AddObject(contact);
oContext.SaveChanges(); // <= Saves the changes
It does solves the problem but it is now throwing another error:
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Unexpected exception from plug-in (Execute): Microsoft.Crm.Sdk.Samples.RegistrationPlugin: System.Exception: Microsoft.Xrm.Sdk.SaveChangesException: An error occured while processing this request. ---> System.TypeLoadException: Inheritance security rules violated while overriding member: 'Microsoft.Crm.Services.Utility.DeviceRegistrationFailedException.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.
at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
at System.Reflection.RuntimeAssembly.GetExportedTypes()
at Microsoft.Xrm.Sdk.KnownProxyTypesProvider.LoadKnownTypes(Assembly assembly)
at Microsoft.Xrm.Sdk.KnownProxyTypesProvider.RegisterAssembly(Assembly assembly)
at Microsoft.Xrm.Sdk.AssemblyBasedKnownProxyTypesProvider.GetTypeForName(String name, Assembly proxyTypesAssembly)
at..................
It seems to me a problem of rights. Can you suggest what I am missing now?
UPDATE: I solved the problem by adding OwnerID = new EntityReference("systemuser", context.UserId)
hmm, I think you don't need to complete the ID field, because when you will create it, the CRM will send you the ID.
Don't know if it could help you, cause I don't create a contact but an incident. But I think the process is the same. So I let you look.
private Guid createCase(IOrganizationService CrmService, Entity email)
{
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
tracingService.Trace("Just to tracing my plugin");
/* CREATE AN ENTITY: incident here, but could be contact, account, ... */
Entity incident = new Entity("incident");
incident["title"] = email.Attributes["subject"].ToString();
incident["caseorigincode"] = new OptionSetValue(2);
EntityCollection ec = email.Attributes["from"] as EntityCollection;
Entity from = ec.Entities.FirstOrDefault();
incident["customerid"] = (EntityReference)from.Attributes["partyid"];
/* END */
tracingService.Trace("tracing 2.");
/* HERE YOU CREATE THE RECORD IN THE CRM */
Guid caseid = CrmService.Create(incident);
/* END */
tracingService.Trace("tracing 3. ID: "+ caseid.ToString());
return caseid;
}

Setting OwnerId of a custom activity

I have created a custom CRM activity that I'm using in a workflow.
I'm using this activity as an InArgument to a custom workflow activity.
In the Execute() method I'm trying to set the OwnerId of the custom CRM activity instance to a system user and calling UpdateObject(entity) on the context object that I have generated using CrmSvcUtil.
[Input("Some name")]
[ReferenceEntity("mycustomactivity")]
[Required]
public InArgument<EntityReference> MyCustomActivity{get;set;}
void Execute(CodeActivityContext context)
{
IOrganizationService svc = context.GetExtension<IOrganizationService>();
var customActivityReference = MyCustomActivity.GetValue(MyCustomActivity);
//MyServiceContext is an OrganizationServiceContext generated using CrmSvcUtil
MyServiceContext servicecontext = new MyServiceContext(svc);
//GetCutomActivityInstance uses the Id to get an instance of the custom activity)
MyCustomCRMActivity activityInstance = GetCutomActivityInstance (servicecontext,customActivityReference.Id);
activityInstance.OwnerId = new EntityReference("systemuser",<SomeGUID>);
context.UpdateObject(activityInstance);
context.SaveChanges();
}
The above does not work, the activity owner is defaulting to my crm user account and is not updated to reflect the owner I'm setting in activityInstance.OwnerId
Any help would be much appreciated.
The owner can't be changed by update. You have to use the AssignRequest (or the built-in Assign-step, see screenshot)
See this answer https://stackoverflow.com/a/7746205/315862

Resources