Showing posts with label Plugins. Show all posts
Showing posts with label Plugins. Show all posts

Monday, June 11, 2012

How to Debug Plugins using Profiler



One can debug CRM plug ins without connecting to CRM server or without remote debugging.

Here are the steps as in how you can use Profiler for debugging plug ins:
   1>     Connect to CRM using plugin registration tool of March SDK 2012.

   2>      Click on Install Profiler
         

   3>     You will find a new node attached to registered plugins “Plugin Profiler”.






   4>     Select a plug-in step and click Profile to enable profiling.



5>     Then start your plugin from MSCRM i.e if your plugin is on update perform  update operation and download the error file.
6>     Then in Visual Studio attach to process “plugin registeration.exe”. Add the breakpoint  from where you would like to debug.



7>     Then click on Debug in plugin registration tool.


8>     In Profile location provide the path of the error log of the plugin.

9>     In Assembly location provide the dll of the plugin from which you got error.

10>     Then select the Plugin class from Plug-in. This drop down will contains all classes present in the dll.

11>     To start debugging just click on Start Plug-in Execution.

      

Tuesday, February 28, 2012

Issue with plug-in in CRM 2011

We had a requirement to do some calculation and update self record of custom entity. We have created a plug-in and registered it on post operation of update event. The code was reading the post image, updating some fields and updating the same.

The plug-in was working fine for single record. But when two records are saved simultaneously, the plug-in was giving below errors randomly.


1. "ValidateOpen - Encountered disposed CrmDbConnection when it should not be disposed"
2. "You cannot create a SqlExecutionContext from another SqlExecutionContext on which OnBeginRequest has not been called"
3. " System.InvalidOperationException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #58919D7E"
4. "System.NullReferenceException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #1638FFA8"

When we checked in the Event viewer then we got that whatever error we get from CRM the Event viewer shows "System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first." error.

After searching on net we found that CRM does not re-initialize the plug-in object again, it uses the same object. In the plug-in, ignore to use class level variables. We had created service object at class level so it was using the same service object for retrieving and updating.

Also we were reading post image and updating the post image as it is. This was also creating a problem. Please create a new object of Entity and then set only those fields which you want to update. Then update the record.

Sometimes this plug-in takes too much time as it was doing so many calculation. We were getting the "Query execution time of 30.1 seconds exceeded the threshold of 10 seconds. Thread: 4; Database: inogic_MSCRM " error when plug-in takes time. To resolve this, please add below keys in the registry on CRM server.
1) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM\OLEDBTimeout
a. In seconds
b. The OLEDBTimeout value controls the SQL time-out value that is used for a single SQL query
c. Set it to 60 seconds


2) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM\ExtendedTimeout
a. In milliseconds
b. The ExtendedTimeout value controls the ASP.NET time-out value
c. Set it to 1,000,000


3) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM\NormalTimeout
a. In milliseconds
b. Specifies the SOAP call timeout for most operations
c. Set it to 300,000

Hope this helps!!

Monday, January 17, 2011

Use Tracing in CRM 2011 Plugins

CRM SDK provides way for you to include the debug details about your plug-in in case you need to trace the plug-in execution. For this you will have to initialize the “ITracingService”. The service provides way to trace the details and display it whenever plug-in fails and throws an exception.

//Initialize the service
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

Once initialized, you just need to add the logical and meaningful details as per your logic using below code,
tracingService.Trace(yourMessage);

Shown below is the example of message shown to the user when plug-in fails and throws exception.


Hope this helps you how to use Tracing in CRM 2011 plugins!

Tuesday, January 4, 2011

CRM 4 to CRM 2011 Upgrade.

Recently we tried to upgrade a highly customized CRM 4 install to CRM 2011 and thought it would be worthwhile to list out our findings for the benefit for all.

CRM 2011 supports both in-place upgrade as well as a fresh CRM 2011 install with a later CRM 4.0 organization import into CRM 2011. We attempted the second way, that a fresh install of CRM 2011 and then tried to import the customized organization of CRM 4.0.

If you install the CRM 2011 beta copy and try the import you will receive the following error.

…lead.Address1 Country length 160 more than original value 100…

This appears to be a bug of the beta version that is probably rectified in the CRM 2011 RC released recently.

After a successful install, you can try to import the CRM 4.0 organization, it auto detects that it is an upgrade and would performs all the necessary operations on the database. Make sure you have another backup of the CRM 4.0 in case the upgrade fails mid-way you will need to go back and restore the original copy and start over again.

After a successful upgrade we found the following items we auto-upgraded to CRM 2011 standards by the upgrade tool.

Scripts:

All the scripts written on form save, load and Change will be automatically converted into web Resource and saved as Library with the name Entityname_main .see the display name below.
Select any Web Resource it looks as shown below.


On click of Form properties for any entity you will find that library is already added on the form and it is called on load event with function name.


The code written on the Load event would be put into a function named Form_onload. The OnSave event is changed to function named Form_onsave and Onchange becomes
Attributename_onchange.

Images:

All the Images used in the Custom entities will be saved as Web resource.

ISV buttons:

Any script written on custom button added through ISV in CRM will be converted to Application Ribbons. Buttons of CRM 4.0 are moved to Ribbons in CRM 2011 as shown below.

Plugins:

Plug-in registered in the CRM for entities will be saved as Plug –In Assemblies and Sdk Message Processing

Plug –In Assemblies shows Name ,Version, Culture Public Key Token and the date on which it was created and last modified date.

Sdk Message Processing shows Message, Event Handler, object type code ,Stage and Status

Workflow:

The Workflows would be auto-upgraded as Processes in CRM 2011 as can be seen from the screenshot below


Form Layout

The form layout is carried over as is during the upgrade from CRM 4.0 to CRM 2011. We however found a conflicts tab added to a couple of forms but were unable to trace the controls placed in this section to any of the controls in the original CRM 4 form.

There are sure to be many more items that were upgraded behind the scenes and we will update the list in times to come. However this is a pretty good reference point to start with for a CRM 4 to 2011 upgrade.

Wednesday, May 26, 2010

Call an Update on the Post Update event of an entity

Now everyone knows, this would result in a recursive loop. It is always preferred that in such cases, the attribute that needs to be updated should be added to the property bag in the Pre-Update event itself.

However, if you do come across a situation where you need to update an attribute on the successful update of another attribute of the same entity, you might want to check the “Depth” property that is available in the Plug-in context.

The Depth property stores the depth of the plug-in that is count of the call that has been made to the same plug-in. In case of our situation, when it calls itself the depth is incremented and we can break the recursion by check for Depth Count > 1.

Wednesday, July 29, 2009

How to use Parameters in Workflows/Plugins

CRM Plugins and Workflows provide the ability to pass external information to the plugins as well as receive information from plugin that can be used for further processing.

Plugins:


In case of Plugins, you can use the Secured Parameter and Unsecured Parameter that is available during Plugin registration to pass static information that can be used by the Plugin.
It is better to use the unsecured parameter as this is available in offline as well.


These parameters are available as parameters to the constructor of the Plugin.


public class AccountCreateHandler: IPlugin
{
public AccountCreateHandler(string unsecure, string secure)
{
// Do something with the parameter strings.
}
public void Execute(IPluginExecutionContext context)
{
// Do something here.
}
}

Workflows:

Workflows are allow for Input as well as Output Parameters. You can use the Input Parameters to pass static information to the Workflows. The Output parameter feature of Workflow is very interesting. The Output parameter defined in the Workflow Plugin, becomes available in the CRM Workflow window. You can use this output parameter in any of the Workflow steps.
It can be used in Wait/If condition block as a value to be checked for.




It can also be used in Create/Update step. Here the Output parameter becomes available only for the attributes that match the parameter data type.



If you had some complex logic to be evaluated before you decide who to assign the records to… you can create a Lookup type of Output parameter and assign the record to this.

Friday, April 24, 2009

Use of Shared Variables in Plugins

Apart from the various improvisations of Plugin over Callouts, is the ability to share data between events of an entity. This option was not available when working with Callouts in CRM 3.0. The workaround we used then was to create an attribute and store the information in an attribute in the Pre Create event. In the Post Create use the value of the attribute.

Plugins in CRM 4.0 have introduced the concept of Shared Variables. So now instead of storing the values in a custom attribute you can store the value in a context variable. This is then available in the Post event for use. It is possible to read/write data into SharedVariables of context.

The following code example shows how to use SharedVariables to pass data from a pre-event registered plug-in to a post-event registered plug-in.

Example:
public class PreTest : IPlugin
{
public void Execute(IPluginExecutionContext context)
{
// Create or retrieve some data that will be needed by the post event handler. You could run a query, create an entity, or perform a calculation.
//In this sample, the data to be passed to the post plug-in is represented by a GUID.
Guid contact = new Guid("{74882D5C-381A-4863-A5B9-B8604615C2D0}");
// Pass the data to the post event handler in an execution context shared variable named PrimaryContact.
context.SharedVariables["PrimaryContact"] = contact.ToString();
}
}

public class PostTest : IPlugin
{
public void Execute(IPluginExecutionContext context)
{
// Obtain the contact from the execution context shared variables.
if (context.SharedVariables.Contains("PrimaryContact"))
{
Guid contact = new Guid((string)context.SharedVariables["PrimaryContact"]);
// perform action on contact.
}
}
}