Showing posts with label Microsoft CRM 2011. Show all posts
Showing posts with label Microsoft CRM 2011. Show all posts

Sunday, April 15, 2012

CRM 4 or CRM 2011 - Change the recipient email address

Both CRM 4 and CRM 2011 always chooses to use the primary email address (emailaddress1) when sending an email to an entity (such as Account or Contact), even though on receiving emails, CRM will map the email to the entity based on any of it's email addresses.

Every now and then I've come across a customer request where they would like to choose which of an entities email address's are used to send an email to the entity (e.g. contact).

So after a lot of experimentation, I've found a reliable way of achieving this. The key is to use a plugin on the pre-event step of the "Send" message (Send Email Message) of the email. I've found that changing the email address to be used before this is unreliable as CRM often overrides the change and re-maps it back to the primary email address.

So, to summarise my example code below:

1) I've added an "new_emailpreference" optionset to the contact entity, which lets you choose which email address is used (emailaddress1, emailaddress2 or emailaddress3).


2) I've attached the plugin as a pre-operation step of the email entity to the "Send" message.

3) The Plugin does the following:
- Grabs the email
- Loops through the "to" address (you could easily extend this to include cc and bcc as well), finding those activity parties which map to a contact.
- For each contact found, it retrieves the contact and determines if emailaddress2 or emailaddress3 has been chosen as the preferred email address to be used instead of the default.
- For that activity party, it then changes the "addressused" property to the chosen email address and updates the email record.

4) When the email gets sent via Outlook or via the Email Router, the email address that is used in the "To" address is set correctly to the email address that was chosen.






Here's the code....Note that it's for CRM 2011, however the code for CRM 4 is very similar and all the fields are the same..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace ExamplePlugin
{
public class Plugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId); // null for SYSTEM user, otherwise User Guid

ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
Guid emailId = Guid.Empty;

if (context.PrimaryEntityName != "email")
{
return;
}

if (context.InputParameters.Contains("EmailId") && context.InputParameters["EmailId"] is Guid)
{
emailId = (Guid)context.InputParameters["EmailId"];

if (emailId == Guid.Empty)
{
return;
}

try
{
// Retrieve the email
var email = service.Retrieve("email", emailId, new ColumnSet(true));
if(email.Contains("to"))
{
EntityCollection activityParties = (EntityCollection)email["to"];

foreach (var activtyParty in activityParties.Entities)
{
if (activtyParty.Contains("partyid") && ((EntityReference)activtyParty["partyid"]).LogicalName == "contact")
{
// Retrieve the contact
var contact = service.Retrieve("contact",
((EntityReference)activtyParty["partyid"]).Id,
new ColumnSet(
new string[]
{ "emailaddress1",
"emailaddress2",
"emailaddress3",
"new_emailpreference" }));

if (contact.Contains("new_emailpreference") && contact["new_emailpreference"] != null)
{
if (((OptionSetValue)contact["new_emailpreference"]).Value == 100000002)
{
if (contact.Contains("emailaddress2") && ((string)contact["emailaddress2"]) != null)
{
activtyParty["addressused"] = (string)contact["emailaddress2"];
}
}
else if (((OptionSetValue)contact["new_emailpreference"]).Value == 100000003)
{
if (contact.Contains("emailaddress3") && ((string)contact["emailaddress3"]) != null)
{
activtyParty["addressused"] = (string)contact["emailaddress3"];
}
}
}
}
}

service.Update(email);
}
}
catch (Exception ex)
{
trace.Trace("Plugin Exception Encountered");
throw new InvalidPluginExecutionException(String.Format("An error occured Excuting the Plugin {0}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace));
}
finally
{
trace.Trace("Plugin Finished Executing");
}
}
else
{
return;
}


}
}
}



Sunday, August 14, 2011

How to break linked reports in CRM 2011

Crm Exception: Message: Linked reports cannot be downloaded, ErrorCode: -2147220970


If you are finding that linked reports are failing to display in CRM 2011, and you get the old "Unexpected Error" message and when you look at CRM's tracing you find the message above, check that you have not removed the "Report Type" field from any of the Reports views.

It seems that the CRM team are using this column to launch linked reports and without it when a report is launched will go to link to download.aspx instead of the specified page.

Saturday, April 9, 2011

Running CRM 4.0 App on CRM 2011 Server

I came accross an issue running software on a CRM 2011 server that was designed for CRM 4.0. There error that was reported is as follows:

Could not load file or assembly 'Microsoft.Crm.Sdk, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)


I was quite surprised to get this after being told by the CRM 2011 SDK that software targeting CRM 4.0 should still be compatible.

After lookin at this link it seems that the CRM 2011 installation is forwarding any reference to the CRM 4.0 assembly to the CRM 2011 assembly via a publisher policy - which aren't 100% compatible.

Although you can get around it by modifying your applications config file (which is described in the link above), this issue can also be fixed now by applying Rollup Pack 1 as indicated in the notes for the Rollup Pack:

The Microsoft.Crm.Sdk.dll file has an incorrect publisher policy registered in the global assembly cache (GAC). Therefore, when you use an application that is built with this dependency, the application fails in Microsoft Dynamics CRM 2011 Server.


Good to know if you intend to run software that was designed for CRM 4.0 on a CRM 2011 server.