CRM 2011 Custom Workflow

I AM LOOKING FOR WORK PLANS, AND I UPDATED THE WORKING CODE HERE. HOPES TO HELP !!

I am creating a workflow that has a plugin for retrieving a contact object from the "FROM" field of an email entry. I am trying to check if this letter exists in the contact organization. Input is the "FROM" message, and the output will return a Contacts object. I was not able to get this code to work, I received various errors or errors, but I know that it does not work. Please help! Thanks in advance!

using System.Activities; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Workflow; using Microsoft.Xrm.Sdk.Query; using Microsoft.Xrm.Sdk.Messages; using System; namespace GetSenderPlugin { public class GetSenderPlugin : CodeActivity { protected override void Execute(CodeActivityContext executionContext) { //Create the tracing service ITracingService trace = executionContext.GetExtension<ITracingService>(); trace.Trace("*****Tracing Initiated*****"); //Create the IWorkflowContext and the IOrganizationService for communication with CRM IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>(); IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); trace.Trace("*****IOrganizationService created*****"); trace.Trace("*****Entity logical Name: " + Email.Get<EntityReference>(executionContext).LogicalName + "*****"); trace.Trace("*****Entity ID: " + Email.Get<EntityReference>(executionContext).Id + "*****"); if (Email != null && string.Compare(Email.Get<EntityReference>(executionContext).LogicalName, "email", false) == 0) { EntityReference retrieveEmail = new EntityReference(); retrieveEmail.Id = Email.Get<EntityReference>(executionContext).Id; retrieveEmail.LogicalName = Email.Get<EntityReference>(executionContext).LogicalName; retrieveEmail.Name = Email.Get<EntityReference>(executionContext).Name; string[] strArrays = new string[1]; strArrays[0] = "from"; ColumnSet columnSet = new ColumnSet(); columnSet.AddColumn(strArrays[0]); RetrieveRequest retrieveRequest = new RetrieveRequest(); retrieveRequest.Target = retrieveEmail; retrieveRequest.ColumnSet = columnSet; trace.Trace("*****Retrieve Request declared*****"); RetrieveResponse retrieveResponse = (RetrieveResponse)service.Execute(retrieveRequest); trace.Trace("*****Retrieve Response executed*****"); Email businessEntity = (Email)retrieveResponse.Entity; trace.Trace("*****businessEnitity retrieved*****"); //ActivityParty activitypartyArray = (ActivityParty)businessEntity.From.FirstOrDefault; foreach (ActivityParty activityParty in businessEntity.From) { trace.Trace("*****Activity Party Name: " + activityParty.PartyId.LogicalName + "*****"); trace.Trace("*****Activity Party Id: " + activityParty.PartyId.Id + "*****"); if (activityParty != null && activityParty != null && activityParty.PartyId != null) { string str = activityParty.PartyId.LogicalName; if (str.CompareTo("contact") != 0) { trace.Trace("*****Not Contact*****"); if (str.CompareTo("account") != 0) { trace.Trace("*****Not Account*****"); if (str.CompareTo("lead") != 0) { trace.Trace("*****Not Lead*****"); if (str.CompareTo("systemuser") != 0) { trace.Trace("*****Not System User*****"); if (str.CompareTo("queue") == 0) { Queue.Set(executionContext, activityParty.PartyId); Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid())); User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid())); Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid())); Account.Set(executionContext, new EntityReference("account", Guid.NewGuid())); } else { trace.Trace("*****User not found*****"); Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid())); Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid())); User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid())); Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid())); Account.Set(executionContext, new EntityReference("account", Guid.NewGuid())); } } else { User.Set(executionContext, activityParty.PartyId); Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid())); Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid())); Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid())); Account.Set(executionContext, new EntityReference("account", Guid.NewGuid())); } } else { Lead.Set(executionContext, activityParty.PartyId); Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid())); Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid())); User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid())); Account.Set(executionContext, new EntityReference("account", Guid.NewGuid())); } } else { Account.Set(executionContext, activityParty.PartyId); Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid())); Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid())); User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid())); Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid())); } } else { trace.Trace("*****Contact assigned*****"); Contact.Set(executionContext, activityParty.PartyId); Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid())); User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid())); Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid())); Account.Set(executionContext, new EntityReference("account", Guid.NewGuid())); } } break; } } else { trace.Trace("*****Email is null*****"); Queue.Set(executionContext, new EntityReference("queue", Guid.NewGuid())); Contact.Set(executionContext, new EntityReference("contact", Guid.NewGuid())); User.Set(executionContext, new EntityReference("systemuser", Guid.NewGuid())); Lead.Set(executionContext, new EntityReference("lead", Guid.NewGuid())); Account.Set(executionContext, new EntityReference("account", Guid.NewGuid())); } } #region Properties [Input("E-mail")] [ReferenceTarget("email")] public InArgument<EntityReference> Email { get; set; } [Output("Account")] [ReferenceTarget("account")] public OutArgument<EntityReference> Account { get; set; } [Output("Contact")] [ReferenceTarget("contact")] public OutArgument<EntityReference> Contact { get; set; } [Output("Lead")] [ReferenceTarget("lead")] public OutArgument<EntityReference> Lead { get; set; } [Output("Queue")] [ReferenceTarget("queue")] public OutArgument<EntityReference> Queue { get; set; } [Output("User")] [ReferenceTarget("systemuser")] public OutArgument<EntityReference> User { get; set; } #endregion } } 

So, we are updating our internal CRM system from 4.0 to 2011, and it was a plugin that was in the workflow. I did not have the source code, so I really did not know what the code was doing. But after I exported the solution, I decompiled the source .dll file. I tried to rewrite the code for CRM 2011, and here is what I have. After I tested the workflow, I received the error message "Expected non-empty pointer." The code goes to the very last line after the loop, after which it gives me an error. Here is the trace:

 Workflow paused due to error: Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Expected non-empty Guid.Detail: <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>Expected non-empty Guid.</Message> <Timestamp>2013-02-21T23:46:37.0376093Z</Timestamp> <InnerFault> <ErrorCode>-2147220970</ErrorCode> <ErrorDetails xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" /> <Message>System.ArgumentException: Expected non-empty Guid. Parameter name: id</Message> <Timestamp>2013-02-21T23:46:37.0376093Z</Timestamp> <InnerFault i:nil="true" /> <TraceText i:nil="true" /> </InnerFault> <TraceText>[Microsoft.Xrm.Sdk.Workflow: Microsoft.Xrm.Sdk.Workflow.Activities.RetrieveEntity] [RetrieveEntity] *****Tracing Initiated***** *****IOrganizationService created***** *****Entity logical Name: email***** *****Entity ID: c49e4c7c-8724-de11-86ce-000c290f83d7***** *****Retrieve Request declared***** *****Retrieve Response executed***** *****businessEnitity retrieved***** *****Activity Party Name: contact***** *****Activity Party Id: 79ed3a33-8eb9-dc11-8edd-00c09f226ebb***** *****Activity Party not null***** *****Contact assigned***** *****foreach ended*****</TraceText> </OrganizationServiceFault> at Microsoft.Crm.Extensibility.OrganizationSdkServiceInternal.Retrieve(String entityName, Guid id, ColumnSet columnSet, CorrelationToken correlationToken, CallerOriginToken callerOriginToken, WebServiceType serviceType) at Microsoft.Crm.Extensibility.InprocessServiceProxy.RetrieveCore(String entityName, Guid id, ColumnSet columnSet) at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Retrieve(String entityName, Guid id, ColumnSet columnSet) at Microsoft.Crm.Workflow.Services.RetrieveActivityService.<>c__DisplayClass1.<RetrieveInternal>b__0(IOrganizationService sdkService) at Microsoft.Crm.Workflow.Services.ActivityServiceBase.ExecuteInTransactedContext(ActivityDelegate activityDelegate) at Microsoft.Crm.Workflow.Services.RetrieveActivityService.ExecuteInternal(ActivityContext executionContext, RetrieveEntity retrieveEntity) at Microsoft.Crm.Workflow.Services.RetrieveActivityService.Execute(ActivityContext executionContext, RetrieveEntity retrieveEntity) at System.Activities.CodeActivity.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation) 
+1
source share
2 answers

I got different errors or no errors, but I know that it does not work

First, I suggest you list the errors in your question. It will be much easier for you to answer and avoid -1. :) Secondly, use the trace service in your workflow.

 ITracingService tracingService = context.GetExtension<ITracingService>(); tracingService.Trace("I'm tracing something...."); 

What happens if a contact with the specified email address is not found? You must handle this. It probably fails. Record the error log to verify this.

+3
source

If I give an answer from the shot, I think the problem is that in some cases you do not get a match and filter everything. Then you get zero somewhere (or try to access a null pointer or try to select an attribute that was not entered so that although it was defined, it would not be serviced).

What exact errors do you get? When will you receive them, and when not?

Also, some problems with the code I noticed (not a solution, but can still be improved).

Enter your name. I think you like ContactReference.

 [Output("output")] [ReferenceTarget("contact")] public OutArgument<EntityReference> ContactRefernce { get; set; } 

I would design the request differently. Since you know which address you want to map, you may need to filter out just that. In addition, it seems to you that you only need a guide for the match based on email, so you only need to get it.

 private Guid MatchSenderWithExistingContact( IOrganizationService service, String fromAddress) { QueryExpression query = new QueryExpression { EntityName = "contact", ColumnSet = new ColumnSet("emailaddress1"), Criteria = new FilterExpression { Filters = { new FilterExpression { Conditions = { new ConditionExpression( "emailaddress1", ConditionOperator.Equal, fromAddress) } } } } }; EntityCollection retrieveMultipleRequest = service.RetrieveMultiple(query); IEnumerable<Entity> entities = retrieveMultipleRequest.Entities; return entities.FirstOrDefault().Id; } 

You might want to place a request announcement in stages. I prefer it this way because it is more convenient when creating advanced queries. However, when you repeat and use the break, it is definitely better, as shown above.

Happy coding!

Maybe you should use tracing. I usually declare the trace object as a member variable in the plugin class, and then write it to each operation. Thus, at least I know that where the dung enters the AC and can record the value of the variables immediately before it.

 private ITracingService trace; public void Execute(IServiceProvider serviceProvider) { trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); _trace.Trace("Tracing successful!"); throw new Exception("Intentional! Nice."); } 

Just keep in mind that the trace will not be displayed unless an uncaught exception occurs. In fact, I deliberately broke the execution on the occasion simply to see what was in the variables. Therefore, remember that if you have a global try-catch, you will need to re-throw the exception manually.

The surface of this method is that you can track both packages and online. It works for all plugins except asynchronous. There are workarounds for this, but that was not the topic of your question, and I was already distracted enough.

+2
source

Source: https://habr.com/ru/post/954771/


All Articles