Archive

Archive for the ‘Plug-Ins’ Category

“Query execution time exceeded the threshold” error in Plugins

Hi,

In one of my requirement I was accessing SSRS service API from my plugin to render and read the report

When the plugin execute the code, I was neither getting the expected result nor any error.

To troubleshoot the problem I open the event viewer and I got a warning stating below

Query execution time of 30.1 seconds exceeded the threshold of 10 seconds. Thread: 30; Database: orgname_MSCRM

Reason :- 

  • My plugin registered on Post Update of Account
  • In my plugin, I was rendering and reading a report which has dataset with “Select * From Account”
  • So the problem is with DB lock
    • On update of ‘Account’, a lock establish
    • In the Plugin code, when I try to render report it tries to execute “Select” statement on “Account” we get the above error

Fix :-

  • I modified my Select statement in report dataset with “No Lock” statement

             i.e., Select * From Account (nolock)

🙂

Sending Email using Email Template in CRM 2011

February 19, 2012 Leave a comment

Hi,

Here is the sample code to send an Email using Email template name.

Before start below are few keywords

  • Template Name   (i.e., Name of the Template)
  • Regarding Id        (i.e., GUID of the entity record which template associated with)
  • Regarding Type   (i.e., Logical name of the entity which template associated with)
  • ActivityParty[]     (i.e., Sender & Receivers Can be Users/Contacts/Accounts/Leads)
  • IOrganizationService crmService

 public void SendEmailUsingTemplate(IOrganizationService crmService,

ActivityParty[] fromParty,  ActivityParty[] toParty,

string templateName,

Guid regardingId, string regardingType)

{

try

{

// Create e-mail message.

var email = new Email

{

To = toParty,

From = fromParty,

DirectionCode = true

};

if (!string.IsNullOrEmpty(templateName))

{

Guid templateId = Guid.Empty;

// Get Template Id by Name

Entity template = GetTemplateByName(crmService, templateName);

if (template != null && template.Id != null)

{

var emailUsingTemplateReq = new SendEmailFromTemplateRequest

{

Target = email.ToEntity<Entity>(),

TemplateId = template.Id,

RegardingId = regardingId,

RegardingType = regardingType

};

var emailUsingTemplateResp = (SendEmailFromTemplateResponse)crmService.Execute(emailUsingTemplateReq);

}

else

{

// “****No email template exists with the given name ****”);

}

}

}

catch (Exception ex)

{

throw;

}

}

     private Entity GetTemplateByName(string title, IOrganizationService crmService)

{

var query = new QueryExpression();

query.EntityName = “template”;

var filter = new FilterExpression();

var condition1 = new ConditionExpression(“title”, ConditionOperator.Equal, new object[] { title });

filter.AddCondition(condition1);

query.Criteria = filter;

EntityCollection allTemplates = crmService.RetrieveMultiple(query);

Entity emailTemplate = null;

if (allTemplates.Entities.Count > 0)            {

emailTemplate = allTemplates.Entities[0];

}

return emailTemplate;

}

How Do I call this method

  • Prepare From and To Users/Contacts/Accounts
  • Pass Service,Template Name,Regarding details

// Prepare “From” activity parties

var from = new ActivityParty

{

PartyId = new EntityReference(SystemUser.EntityLogicalName, {GUID of User})

};

var fromParty = new[] { from };

// Prepare “To” activity parties

var to = new ActivityParty

{

PartyId = new EntityReference(SystemUser.EntityLogicalName, {GUID of User})

};

var toParty = new[] { to };

var orgProxy = new OrganizationServiceProxy(organizationUri, homeRealmUri, credentials, null);

IOrganizationService orgnaizationService = orgProxy;

Guid regardingntityId={GUID of record} // Ex – Guid of contact

string regardingEntityName = “contact” // Logical name ‘contact’

SendEmailUsingTemplate(orgnaizationService , fromParty, toParty, “templateName”, regardingntityId, regardingEntityName);

Hope it helps 🙂

Fetching user security roles using Linq in CRM 2011 Plug-in’s

January 17, 2012 5 comments

Hi,

Below is the sample code to fetch the User’s security roles based on the “User Id” in the Plug-in’s using Linq

        /// <summary>

/// Returns the list of User security role names

/// </summary>

private List<string> GetUserRoles(IOrganizationService service, Guid userId) {

// Create Query Expression to fetch Role Entity

var query = new QueryExpression

{

// Setting the link entity condition and filter condition criteria/

LinkEntities =

{

new LinkEntity

{

LinkFromEntityName = “role”,

LinkFromAttributeName = “roleid”,

LinkToEntityName = “systemuserroles”,

LinkToAttributeName = “roleid”,

LinkCriteria = new FilterExpression

{

FilterOperator =

LogicalOperator.And,

Conditions =

{

new ConditionExpression

{

AttributeName =  “systemuserid”,

Operator =    ConditionOperator.Equal,

Values =

{

userId

}

}

}

}

}

},

ColumnSet = new ColumnSet(true),

EntityName = “role”

};

// Obtain results from the query expression.

var userRoles = service.RetrieveMultiple(query);

// Get the usre role names collection

var roleNames = new List<string>();

if (userRoles != null)   {

roleNames.AddRange(

from entrole in userRoles.Entities

select entrole as Role

into role

where role != null && role.RoleId != null

select role.Name);

}

return roleNames;

}

How do I call this method :-

  • In your plug-in, pass the service and User Id as parameters to this method

public void Execute(IServiceProvider serviceProvider) {

context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

var service = serviceFactory.CreateOrganizationService(context.UserId);

// Get the current users Security Roles Name’s

Var roleNames = GetUserRoles(service, this.context.UserId);

}

Hope it helps 🙂

Setting default view using Plug-in’s in CRM 2011

January 17, 2012 7 comments

Hi,

We often get the requirement to set a default view based on some criteria (Ex – Could be based on logged in user role, etc…). We can achieve this using a Plug-in.

Little insight :-

  • When you click on an entity (i.e., ‘Contacts’ in my sample) in CRM application, In the background a “RetreieveMultiple” method call  happens on “savedquery” entity.

'Contacts' link

  • “savedquery” is a system entity in CRM which stores the meta data of all the views in the system

Plug-in Logic :-

  • We register a Plug-in for the RetreieveMultiple message on the savedquery entity to be executed in the post stage
  • From “Outputparameters” fetch the “BusinessEntityCollection” (i.e., Views of particular entity)
  • Loop through the views and set “isdefault” property to “true” for the desired view

–          Below is the sample code

public void Execute(IServiceProvider serviceProvider)

{

this.context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

var service = serviceFactory.CreateOrganizationService(this.context.UserId);

if (this.context.InputParameters.Contains(“Query”) && this.context.InputParameters[“Query”] is QueryExpression && this.context.Stage == 40){

var qe = (QueryExpression)this.context.InputParameters[“Query”];

if (qe.Criteria != null) {

var condition = (ConditionExpression)qe.Criteria.Conditions[1];

// “Type code” of entity you want default views ( Object type code of ‘contact’ is 2)

//  Refer Useful article on how to get “Object Type Code”

if (condition.Values[0].Equals(2)) {

// Name of the view you want to set as Default

string ourDefaultView = “My custom view – Contacts”;

if (!string.IsNullOrEmpty(ourDefaultView)){

var collection = (EntityCollection)this.context.OutputParameters[“BusinessEntityCollection”];

collection = ChangeViewCollection(ourDefaultView, collection);

this.context.OutputParameters[“BusinessEntityCollection”] = collection;

}

}

}}}

/// <summary>

/// Setting IsDefault property of views

/// </summary>

private EntityCollection ChangeViewCollection(string ourDefaultViewName, EntityCollection records){

foreach (Entity record in records.Entities){

string viewName = (string)record[“name”];

if (viewName.Equals(ourDefaultViewName)){

record[“isdefault”] = new bool();

record[“isdefault”] = true;

}

else {

record[“isdefault”] = new bool();

record[“isdefault”] = false;

}

}

return records;

}

Plug-in Registration Steps :-

Message Name – RetrieveMultiple

Entity – SavedQuery

Stage – post

  • Register the assembly & Refresh the CRM application

@@ 🙂 Here goes my 50th article. Thanks for all your visits and valuable comments 🙂 @@

How to Debug Plug-Ins in CRM

January 13, 2012 7 comments

Hi,

Sometimes you might get wonder (even frustrated) why the debugger is not hitting the break point in your Plug-In code file.

Below are the Checklist to perform prior to start the debugging of your Plug-in assembly.

  • Ensure that your plug-in assembly is signed (See)
  • Rebuild the plug-in assembly
  • Reset the IIS (i.e. Open command prompt and run ‘iisreset’ command)
  • Restart CRM Asynchronous Service on CRM server (Only in case of asynchronous plug-in or Custom workflow )
  • Copy the .pdb file and your .dll file to server’s assembly (i.e., ..\Program Files\Microsoft Dynamics CRM\Server\bin\assembly)
  • Open the Plug-in Registration Tool (Download)
  • Browse the dll from your Plug-Ins projects “bin\debug” folder
  • In Plug-in Registration Tool , Choose “Specify the location where assembly should be stored” option as “Disk”
  • Register the step
  • Register the image(s) if any
  • Attach the process by opening the Plug-in project in the Visual Studio and then
    • From menu choose “Debug -> Attach to Process…” ( or Click ‘Alt + Ctrl + P’)
    • Select  w3wp.exe (i.e.,Worker Process), if plug-in is Synchronous
    • Select CRMAsyncService.exe, if Plug-in is asynchronous or Custom workflow.
Attaching Worker Process (w3wp.exe)

Attaching Worker Process (w3wp.exe)

  • You are all set by now and put a break point (Click F9) on relevant code line.

In case of Remote Debugger :-

  • If your CRM server machine is different from your development machine
  • Install “Visual Studio Remote Debugger” (Download) on CRM server machine
  • Run it as “Administrator”
  • Follow the same steps above except while attaching Process, in the “Attach to Process” window, set “Qualifier” as “CRM server machine”

Debug plug-in in outlook offline mode

  • Clean and rebuild the plug-in solution on your machine using visual studio
  • Register the plugin on the server
  • Synchronize the organization with the outlook
  • Go Offline
  • Attach the debugger to the process “Microsoft.Crm.Application.Hoster.exe
  • Place a breakpoint in the code.
  • Run the scenario

Hope it helps 🙂

Auto numbering logic in CRM 2011

January 11, 2012 Leave a comment

Hi,

Auto numbering feature is one of the most frequently asked requirement in CRM projects and below is the sample.

In my sample, I am going to generate an auto number to the each ‘Contact’ that create under a particular ‘Account’. The auto number format will be “Contact – 001, Contact – 002,….”.

To achieve the above requirement,  I am going to

  • Create a Plug-In on “Pre – Create” event of the contact
  • Use the CRM early bound

Steps :-

  • Generate  “Organization Service Context Class” using the Code Generation Tool (CrmSvcUtil.exe). (See)
  • You will get a “ServiceContext.cs” file with all entity wrapper classes.
  • Create a new Plug-In project and add the generated “ServiceContext.cs” file
  • Add a new class “ContactAutoNumber.cs” to the project and paste below code

public class ContactAutoNumber: IPlugin {

private Entity dynEntity;

private contact objContact;

public void Execute(IServiceProvider serviceProvider)        {

this.context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

var service = serviceFactory.CreateOrganizationService(this.context.UserId);

if (this.context.InputParameters.Contains(“Target”) && this.context.InputParameters[“Target”] isEntity)  {

// Obtain the target entity from the input parmameters.

this.dynEntity = (Entity)this.context.InputParameters[“Target”];

// Cast “Dynamic Entity” to “Contact”

this.objContact = this.dynEntity.ToEntity<contact>();

}

// Instantiate “Service Context” (i.e., The name of ‘Organization Service Context Class’)

var svcContext = new ServiceContext(service);

// Get the “Contact” list under parent ‘Account’ by “AccountId”

var contacts = svcContext.ContactSet.Where(

ns => (ns.AccountId.Id ==this.objContact.AccountId.Id));

// Get the count of the contacts

var cntContacts= Enumerable.Count(contacts);

// Increment the suffix count

var strFormat = (cntContacts + 1).ToString();

// Logic to prepare format “001,002,…..”

if (strFormat.Length < 3){

strFormat = (strFormat.Length == 1) ?

“00” + strFormat : “0” + strFormat;

}

// Set the auto number to your attribute

this.objContact.{Attribute_Name}= “contact – “ + strFormat;

}

}

}

Plug – In Registration step :-

Message : Create

Entity : contact

Statge : Pre

  • Register the Plug -in as above mentioned

Hope it helps 🙂

“The context is not currently tracking the entity” exception in CRM 2011

January 3, 2012 1 comment

Hi,

You may come across below exception when you are trying to Create/Update child record in the Parent record context of Plug-in using XRM Linq

Context is not currently tracking entity

Context is not currently tracking entity

Scenario :-

  • Imagine you have registered a “Post Update” Plug-in on ‘Account’ entity which Updates an associated ‘Contact’ entity
  • Here the Plug-in runs under Parent Entity Context (i.e., Account)
  • When you try to update child record (i.e.,Contact) it throws out exception, since the context knows nothing about ‘Contact’

Fix :-

  • The solution is call the context.Attach() method; Call this method before calling the Update method (Refer below code)

IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

var ServiceContext= new XrmServiceContext(service);

Guid contactGUID= (from c in xrm.ContactSet where c.FullName == “Farest Chand” select c.Id).FirstOrDefault();

ServiceContext.Contact objContact= new ServiceContext.Contact {  Id = contactGUID,  FullName= ‘Rajeev’};

ServiceContext.ClearChanges();

ServiceContext.Attach(objContact);

ServiceContext.UpdateObject(objContact);

ServiceContext.SaveChanges();

Hope it Helps 🙂

“Object of type can not be converted to type ‘IBusinessEntity’ ” exception with crm Early Binding

December 28, 2011 3 comments

Hi,

You may come across below exception in Plug-Ins, while performing Create/Update operation  using CRM early binding

Exception: Unhandled Exception: System.InvalidOperationException: Object of type ‘entity_name‘ can not be converted to type ‘IBusinessEntity’

Fix :-

  • You need to add below line in your Plug-in project’s “AssemblyInfo.cs” file (Navigate to project folder and go to ..\Properties\AssemblyInfo.cs)

[assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()]

AssemblyInfo.cs

AssemblyInfo.cs

  • Clean and Rebuild the solution
  • Register the plug-in assembly

Hope it helps 🙂

 

Activate or Deactivate record in CRM 2011

October 18, 2011 4 comments

Hi,

We can Activate\Deactivate record using “SetStateRequest“. Below is the code snippet.

private void SetEntityStatus(IOrganizationService service, Guid recordGUID, string entityName)        {

SetStateRequest setState = newSetStateRequest();

setState.EntityMoniker = newEntityReference();

//Pass GUID of the record to be activated or Deactivated

setState.EntityMoniker.Id = recordGUID;

setState.EntityMoniker.Name = entityName;

setState.EntityMoniker.LogicalName = entityName;

//Setting ‘State’ i.e., (0 – Active ; 1 – InActive)

setState.State = new OptionSetValue();

setState.State.Value = 0/1;

//Setting ‘Status’ i.e., (1 – Active ; 2 – InActive)

setState.Status = new OptionSetValue();

setState.Status.Value = 1/2;

SetStateResponse setStateResponse = (SetStateResponse)service.Execute(setState);

}

Hope it helps 🙂

Missing prvReadAsyncOperation privilege exception

September 21, 2011 3 comments

Hi,

Today my plug-in has thrown “Missing prvReadAsyncOperation privilege ” exception for user with one of the security role.

Fix:-

  • We need to grant Read Priveliege of System Job for the security role
  • Open the Security Role and go to Customization tab
  • Refer below screen
prvreadasync-privilage

prvreadasync-privilage

 

Hope it helps 🙂