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.