Archive
Reading WCF client binding configurations from plug-in
In one of my requirement I have to call my custom WCF service method from plug-in.
In this scenario my plug-in is WCF client and I have to read client binding configuration from plug-in.
Below are the ways you can read the binding configuration details from plug-in
- Synchronous plug-in
- In case of synchronous plug-in, you can place binding configuration in root <web.config> file of CRM application server
- Open the Web.config from path “C:\Program Files\Microsoft Dynamics CRM\CRMWeb\web.config”
- Find <System.ServiceModel> node and place the client binding configuration
- After placing the configuration, the <System.ServiceModel> looks as below
- Asynchronous Plug-in
- Since async plug-ins host on “CRM Async Service”, place the configuration details in “CrmAsyncService.exe.config” file
- Open the “CrmAsyncService.exe.config” file from path “C:\Program Files\Microsoft Dynamics CRM\Server\bin\CrmAsyncService.exe.config”
- Add <System.ServiceModel> node and place the client binding configuration
- After placing the configuration, the <System.ServiceModel> looks as below
🙂
“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
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
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
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.
- “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
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.
- 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
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
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
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
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()]
- Clean and Rebuild the solution
- Register the plug-in assembly
Hope it helps 🙂
Activate or Deactivate record in CRM 2011
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 🙂