Advertisements

Archive

Posts Tagged ‘Plug-in’

Complete a transaction and throw exception in CRM Plug-in

July 31, 2016 3 comments

Recently I was asked a question in my blog on how to achieve below scenario in plug-in.

  • User try to save Account record by providing data in multiple fields.
  • Create Plug-in should check whether any other Account already exists in CRM with provided data.
  • If match found, update the existing record and display “Cannot save the Account as Account with data already exists”
  • If no match found, create an Account.

Challenge:

  • If ‘Account’ match found, system should update matched Account and at the same time throw message “Cannot save the Account as Account with data already exists”.
  • To display message Plugin must throw Execution with message which would roll back the update operation.

Proposed Design:

  • Register a Plug-in on “PreCreateAccount” with following logic, if matching ‘Account’ already exists with input data.
  • To complete update operation,
    • Use “ExecuteMultipleRequest” with option “ContinueOnError = true” which completes transaction.
    • Instantiate ‘UpdateRequest’ and execute using “ExecuteMultipleRequest”
  • In next line, throw exception with message

Plug-in Code:

// Get the matched Account
Entity matchedAccount = new Entity(“account”);
UpdateRequest reqUpdate = new UpdateRequest();
reqUpdate.Target = matchedAccount;

// Use this to complete the update operation even on an exception
ExecuteMultipleRequest reqMultiple = new ExecuteMultipleRequest(){
Requests = new OrganizationRequestCollection(),
Settings = new ExecuteMultipleSettings(){
ContinueOnError = true,
ReturnResponses = false
}
};

// Add Update Request to Multiple Request.
reqMultiple.Requests.Add(reqUpdate);

// Trigger the Execute Multiple.
crmOrgService.Execute(reqMultiple);

// Use this to display message to user
throw InvalidPluginExecutionException(“Cannot save the Account as Account with data already exists”);

🙂

Advertisements
Categories: CRM Tags: , ,

Specified domain does not exist or cannot be contacted – Error connecting to SharePoint from CRM on premise Plug-in

December 4, 2015 Leave a comment

In one of our Plug-in, we have logic to upload the note’s attachment to SharePoint server.

Everything was working as expected until we got this unexpected exception ‘Specified domain does not exist or cannot be contacted’.

Domain Does Not Exist

Domain Does Not Exist

Reason & Fix:

  • Reason for this exception while updating Plug-in Assembly, I accidentally set the ‘Isolation mode’ to ‘Sandbox’.
  • Since there was no trust established with SharePoint server, plug-in thrown exception when tried to upload file to SharePoint Document Library.
  • Changing Isolation Mode to ‘None’ solved our issue.
Isolation Mode - Sandbox

Isolation Mode – Sandbox

  • Alternative way for Isolation ‘none’ is to establish trust. Refer this article on how establish trust.

🙂

Categories: CRM Tags: , , ,

Passing configuration data using Plug-in registration tool (Secured vs. Unsecured)

October 22, 2012 1 comment
  • CRM plugin registration tool contain “Unsecure & Secure” configuration sections while registering a “Step”
  • We can pass configuration data and can be used in the plug-in logic.
Plug-in registration - Secured and Unsecured sections

Plug-in registration – Secured and Unsecured sections

Secured vs. Unsecured

Below are key differentiations between Secured and Unsecured data configuration

  • Access
    • Data passed through “Unsecure” section is PUBLIC (i.e., It can be read by any user in CRM).
    • Only users with “System Administrator” role have access to the data passed through “Secure” configuration section
  • Storage
    • “Unsecure” config data will be stored along with the Plugin ‘Step’ registration information (i.e., In SdkMessageProcessingStep entity)
    • “Secure” config data will be stored in a separate entity named “SdkMessageProcessingStepSecureConfig
      • Only “System Administrator” has Read access on this entity, hence only users with ‘Sys Admin’ role can access this data
    • Both “Secured & Unsecured” configuration data stored as “Plain text” in DB
  • Outlook Sync
    • “Unsecured” configuration data is downloaded to the user’s computer when they go offline making it Unsecure
    • “Secured” configuration data is NOT downloaded to User’s Computer when they go Offline

How to read Configuration data in Plug-in

In our plug-in class, we can define a constructor that passes two parameters (i.e., unsecure configuration and secure configuration)

public class AccountCreateHandler: IPlugin{

public AccountCreateHandler(string unsecure, string secure){

// Do something with the parameter strings.

}

public void Execute(IPluginExecutionContext context){

// Do something here.

}

}

Note :- If you want to read “Secure” configuration in the plug-in code, either change the user context in plugin registration as “CRM administrator ” or Impersonate to “CRM Administrator” role user in the code

🙂

Plug-ins in CRM 2011 – Useful points

Plug-in stages

  • Pre validation
    • Registered Plug-in run before the form is validated
    • Useful if you want to implement business logic before the actual validation starts.  i.e., Changes made in plug-in won’t be saved if the validation of the main system plugins complain because the changes are outside the database transaction.
    • Ex – Some “delete” plug-ins. Deletion cascades happen prior to pre-operation, therefore if you need any information about the child records, the delete plugin must be pre-validation.
  • Pre -operation
    • After validation and before the values are saved to the database
  • Post operation
    • Plugin will run after the values have been inserted/changed on the database

Database Transactions in Plug-Ins

  • Plug-ins may or may not execute within the database transaction
  • You can check if the plug-in is executing in-transaction by reading the ‘IsInTransaction‘ property of IPluginExecutionContext
  • Stages 20 and 40 are part of the database transaction while stage 10 and 50 may be part of the transaction
  • If plugin throws an exception, every action done during the transaction will be rollback

Few more Points

  • Whether a plug-in executes synchronously or asynchronously, there is a 2 minute time limit imposed on the execution of a (message) request.
  • If the execution of your plug-in logic exceeds the time limit, a Timeout exception is thrown
  • If a plug-in needs more processing time than the 2 minute time limit, consider using a workflow or other background process
  • ‘Pre-operation’ operations that CRM will do will not be carried out in pre-validation stage.
    • If you are deleting a record that has many-to-many relationship records with another entity; these relationship records will still be available in pre-validation stage, but not in pre-operation stage.
  • “Target” entity (i.e., pluginContext.InputParameters[“Target”])
    • It’s the entity on which plug-in registered
    • It only contains “dirty” attributes. if you convert to early bound, the value of the unchanged attribute will be null

Useful MSDN article :)

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 🙂

Sending an Email using CRM 2011 Plug In

August 3, 2011 27 comments

Hi,

In one of my recent requirements, I had to send an Email using Plug-in (Late Binding). Below is the code snippet.

private void SendEmail(IOrganizationService service, Guid recieverUserId, Guid senderUserId, Guid regardingObjectId, string emailBody, string emailSubject)

{

Entity email = new Entity();
email.LogicalName = “email”;

//Set regarding object property (i.e. The entity record, which u want this email associated with)

EntityReference regardingObject = new EntityReference(“{entity_name}”, regardingObjectId);
email.Attributes.Add(“regardingobjectid”,regardingObject);

//Defining Activity Parties (starts)

EntityReference from = new EntityReference(“systemuser”, senderUserId);

EntityReference to = new EntityReference(“systemuser”,recieverUserId);

//Derive from party

Entity fromParty = new Entity(“activityparty”);
fromParty.Attributes.Add(“partyid”,from);

//Derive to party

Entity toParty = new Entity(“activityparty”);
toParty.Attributes.Add(“partyid”, to);

EntityCollection collFromParty = new EntityCollection();
collFromParty.EntityName = “systemuser”;
collFromParty.Entities.Add(fromParty);

EntityCollection collToParty = new EntityCollection();
collToParty.EntityName = “systemuser”;
collToParty.Entities.Add(toParty);

email.Attributes.Add(“from”,collFromParty);
email.Attributes.Add(“to”, collToParty);

//Defining Activity Parties (ends)

//Set subject & body properties
email.Attributes.Add(“subject”,emailSubject);
email.Attributes.Add(“description”, emailBody);

//Create email activity

Guid emailID = service.Create(email);

//Sending email

SendEmailRequest reqSendEmail = new SendEmailRequest();
reqSendEmail.EmailId = emailID;//ID of created mail
reqSendEmail.TrackingToken = “”;
reqSendEmail.IssueSend = true;

SendEmailResponse res = (SendEmailResponse)service.Execute(reqSendEmail);

}

This is tested code and you can use as it is. Hope it Helps 🙂