Advertisements

Logging in CRM entity in Microsoft Dynamics CRM

The tool is available for download at the codeplex site: https://enterpriselogger.codeplex.com/.

The entire documentation of the tool and how to use it can be found in the documentation tab in the codeplex site. In case you want to keep reading this blog, I suggest you go back to the link:  https://debajitcrm.wordpress.com/2014/06/26/enterprise-logger-for-microsoft-dynamics-crm/ and gather an idea about the tool and what it does.

Now we would see how we can configure the Enterprise Logging tool for CRM to log in the CRM entity. This is the most simplest of configuration.

The logging would happen in the “Error Log” entity which is comes with the Xrm Logger solution.

Please Note: If you are using Crm Entity as the logging mechanism, you should make sure that all your security roles should have Organization Level Read, write and Create access on the Error Log entity. Sounds difficult? No worries, I have the RolePrivilegeUtitlity.exe executable, which I would provide along with this tool, which will do that for you.

 

Now I have selected “Crm Entity” as my logging mechanism and saved the configuration.

image

Now I again go in CRM and create an account. Next I open Advanced Find in CRM and check for the Error Log entity.

image

image

Isn’t this truly interesting. You have changed the Logging Mechanism without changing a single line of code!

 

Please read this very carefully if you are using the CRM entity as your logging mechanism

If you are invoking the Logger methods from CRM, where CRM maintains transactions (synchronous plugin and synchronous workflows(CRM 2013 only)), the logger tool would log an error in the Error Log entity only if the passExceptionToUser parameter in the method of the logger is set to false. If it is set to True, the error would be thrown back to the user with the complete stack trace but no Error Log record would be created. However no such restrictions for Warning and Message Logging.

 

Another great advantage of the tool is say you are moving your organization from on-premise to online, no change in the logging code is required. All you need to do is come back to the configuration page of the Xrm Logger solution and select Office 365 and then CRM would start to log in the Error log Entity.

Advertisements

Logging in custom database in Microsoft Dynamics CRM

The tool is available for download at the codeplex site: https://enterpriselogger.codeplex.com/.

The entire documentation of the tool and how to use it can be found in the documentation tab in the codeplex site. In case you want to keep reading this blog, I suggest you go back to the link:  https://debajitcrm.wordpress.com/2014/06/26/enterprise-logger-for-microsoft-dynamics-crm/ and gather an idea about the tool and what it does.

 

Here we would see how we can log in custom database from CRM just by tweaking the configuration page without even changing a single line of code. Please note that for this to work, the users should have access to the custom database with write permissions to the table where logging would be done.

I come back to the configuration page of “Xrm Logger” solution and this time I select “Database” as the logging mechanism.

image

The following information needs to be entered

  • Connection String :  the connecting string to the custom database
  • Table name : the name of the table where logging would be done.
  • Message – The column name of the table where the Error Message/ Warning/ Message logged by the logger would be stored
  • Message Type – The column name in the custom database table that would store the value indicating where it is Error/ Warning/ Message
  • Stack Trace – The column to store the Stack Trace information in case of an error
  • Source Method – The column to store the name of the method from where the logger has been invoked. Basically whatever you pass in the parameter methodSource of the logging method, that value would be stored here
  • Log Time – The timestamp when the logging happened.

 

I have a custom database where the logging would be done. I enter all the fields and save the configuration. Please check for the screen shots below.

Screenshot for the database where logging would be done.

image

 

Values entered in the configuration entity

image

Please note that the connection string is stored in the CRM database Encoded and any user other than the system administrator would not be able to view the connecting string in plain text format.

Now I go again in CRM and create an account. And when I query the Log Table the following is the screenshot of what I get.

image

And you have logged in your custom database without changing a single line of code. Hope this would surely help.

In case this is not what you are looking for and you intend for and you want to keep the logging totally within the bounds of CRM, this tool won’t disappoint you. Please refer to the link – https://debajitcrm.wordpress.com/2014/06/26/logging-in-crm-entity-with-enterprise-logger-tool/

Logging in EventViewer in Microsoft Dynamics CRM

The tool is available for download at the codeplex site: https://enterpriselogger.codeplex.com/.

The entire documentation of the tool and how to use it can be found in the documentation tab in the codeplex site. In case you want to keep reading this blog, I suggest you go back to the link: https://debajitcrm.wordpress.com/2014/06/26/enterprise-logger-for-microsoft-dynamics-crm/ and gather an idea about the tool and what it does.

Now we would see how the same can be configured to log in the Event Viewer.

All you need is to come back to the solution configuration page and this time select the option “Event Viewer”.

image

As you can see, you have to specify the “Event Source” as well the “Event Id”. Please note that the Event Source specified, if not found, the logger would try to create the source. If the user under whose context, the logging method is called, does not have that permission, it would fail. I would suggest you create an event source with the same name prior to logging.

Once we save the configuration, we now again try to create the account. If you are continuing from the previous article, please note that I have enabled back the pre-account step of the plugin for logging. Once the create operation is completed, we open the event viewer and check. Following is the screenshot of what we have in the event viewer.

image

Voila!. We have changed the logging mechanism for the entire solution from file based to event viewer based without changing a single line of code. Isn’t that great and I am pretty sure this would save a lot of your time.

To learn how to configure logging in a custom database of your choice, please refer to the link – https://debajitcrm.wordpress.com/2014/06/26/logging-in-custom-database-with-enterprise-crm-logger/

Error Logging in Microsoft Dynamics CRM

Would like to share with you all a tool which I have built for logging in Microsoft Dynamics CRM. The tool works for both CRM 2011 and CRM 2013 versions of on-premise/ IFD/ Office 365 environment. It also gives you the option to perform the log operation in File/ Eventviewer/ Custom Database/ CRM entity as per your choice. And guess what, you can do all this with just a few configuration changes.

As my all other tools, this tool is also available for download at codeplex site URL – https://enterpriselogger.codeplex.com/.

The detailed documentation of this tool is provided in the documentation tab of the codeplex site. Or you can keep reading this blog to understand how the tool works.

Don’t want to go through huge documentation? No worries. The following YouTube links would give you a visual approach about how to use this tool in your CRM Organization.

Introduction to Enterprise Logging toolhttp://youtu.be/l2-cbZDcgIo

Event Viewer Logginghttp://youtu.be/j-MVx5w16t0

Database Logginghttp://youtu.be/zvy370pij8U
Crm Entity Logginghttp://youtu.be/tRi38Fpku-o

 

The tool consists of two components. A managed solution which would help in configuration and an assembly which you need to refer from your classes to do the actual logging stuff. Apart from that, there will be an utility which you need to run for the first time after you install the solution. The utility would provide the required privileges to all your security roles in the system to the logging entities to enable smooth functioning of the logging tool.

 

Lets first focus on the configuration part. After you install the managed solution “Xrm Logger”, open the solution and move to the configuration page of the solution. Please check the below screenshot for the same

 

image

 

You would be presented with the following options:

  • 1. Select your installation type and depending on that the logging mechanism would change.
  • 2. Enable or disable logging using the “Enable Logging” checkbox.
  • 3. Ability to configure logging at individual plugin step level.
  • 4. Ability to configure logging at custom workflow assembly level.

 

Let’s first concentrate on the on-premise/ IFD installation. The moment we select On-Premise/ IFD option, we get the following options for logging as shown in the below screenshot

image

Each of these options is explained under separate headers below

File Logging:

Once we select File Logging, the users is asked to provide a file path to log. As the message in red suggests, the file can be local to the CRM server or should be accessible over the network from the CRM Server. Also the users of CRM should have write permissions to the file because the logging to this file would be done based on the user’s context from whom the logger utility is invoked.

I have entered D:\Logging\Logger.txt as the log file path and saved. Please check for the screenshot below.

image

Once you have configured your logging, let us now concentrate on the other part of it. The second component of this tool is the Xrm.Logging.dll which you need to refer in your plugins/ custom workflow assemblies/ custom applications or any application through which you are interacting with CRM. I have created a sample plugin project for demo and have referenced the DLL in the project. Please check for the screenshot below.

image

Once you are refer it, include the namespace “Xrm.Logging” in your plugin project and you are ready to use the logger in your code.

image

 

The logger dll gives you option to log errors/ warnings and messages. Lets first explore the parameters that are required for logging an error. For that we invoke the method TraceHelper.LogError.

To generate an error, I am forcibly calling the Retrieve of account on any arbitrary GUID. Hence it would throw an error. The entire code is shown in the screenshot below.

image

The LogError method has two overloads for FaultException and General Exception respectively. Use the parameters as per the documentation which is very detailed and also suggests when to use what as you can see from the screenshot above. As you can see the logger provides you an option to also show custom error message to the business user and also an option whether to pass the exception back to the user. So in the above example, the detailed error would get logged in the Logger.txt file and the business user would get a pop-up which would show “custom error message”. Now we also have an option to suppress the exception setting the “passExceptionToUser” as false. In that case the system would not throw the error back to the user. By default if you do not specify the parameter it would be set to true.

Once we are done with the code, build the plugins project. Now before regsitering, we first have to merge the Xrm.Logging.dll and Plugins dll. You can do it from the command prompt using the ILMerger.exe utility or using the ILMege tool from codeplex. Personally I prefer to use the latter as it is wonderful tool and you do not need to remember all the parameters that you need for merging. The tool is available for download at:  http://ilmergegui.codeplex.com/

image

As you can see I have added the Plugin and the Logging assembly and have selected my plugin assembly as the Primary assembly (check the checkbox beside the assembly to select the primary assembly). Next select “Sign with Key File” option and choose the strong name key that you used to sign your plugin assembly. Put the path for the merged file output. Choose the debug option as true in case you need to debug the merged assembly.

Now register the merged dll in the plugin registration tool and add the required steps. I have registered the plugin to fire on the account-precreate. Now when i try to create an account the following is the screenshot I get.

image

We get Business Process Error and as you can see, the custom error message is shown to the user. Now let us open the Logger.txt file.

image

The detailed error is logged in the text file. One big advantage of using the logging solution is it gets the entire stack of error message i.e it parses through the entire inner exception of the exception object.

Now say you want to log an exception in the text file but you do not want to show the message to the user or in other words you want to suppress the error. I will just come to the code and set the parameter passExceptionToUser:false. Check for the screen shot below.

 

image

Now when we create the account, the account is now created successfully in-spite of the exception. However the error message is still logged in the logger file.

Now say you want to disable logging for the account pre-create step altogether. No need to change any code. All you need to do is go back to the solution and uncheck the checkbox for the plugin step and save. Check for the screenshot below.

image

Now even though you have logging code, it would simply bypass and not log anything. Similarly you could use the LogMessage and LogWarning to log messages and warnings respectively.

image

P.S – The logging configuration for plugins and workflows would only be respected if you pass the optional parameter of plugincontext or workflow context depending from where you are calling. If you do not pass the parameter in the logging method, it would always log even if you disable logging for the step.

Now we would move to Event Viewer logging. To see how it works, please follow this link – https://debajitcrm.wordpress.com/2014/06/26/logging-in-eventviewer-with-enterprise-crm-logger/

{Dynamics CRM} Programatically Assign privilege to security role for an entity in MSCRM

Recently in my project, I had a requirement where I needed to assign security privilege to all the roles in the system to a custom entity Programatically. Let’s see how we can achieve the same.

Whenever a custom entity is added in CRM, CRM internally created eight privilige records for the entity for the privileges – Read, Create, Write, Assign, Delete, Append, AppendTo and Share

The name of the privilege records create would be in the format of prv<privilege><entitylogicalname>. So if the logical name of the entity is crmtr_testentity1  then for create privilege, the privilege name in CRM for Create would be prvCreatecrmtr_testentity1. The code below would fetch all the privileges for the entity crmtr_testentity1.

var orgService = GetOrganizationService();
var query = new QueryExpression(“privilege”);
query.ColumnSet = new ColumnSet(true);
query.Criteria.AddCondition(new ConditionExpression(“name”, ConditionOperator.Like, “%crmtr_testentity1%”));
var collection = orgService.RetrieveMultiple(query);

You need to implement the method GetOrganizationService() which would return the OrganizationServiceProxy instance.

Lets see what is returns. In the screenshot below, I have attached the results that I can view in debugger

Image1

As you could see, all the eight privileges for this record has been returned.

Now for demo purpose let us give Marketing Manager security role User level create and business unit level for Write privilege. The code below does the same.

foreach (var prv in collection.Entities)
{
switch ((string)prv[“name”])
{
case “prvCreatecrmtr_testentity1”:
{
AddPrivilegesRoleRequest req = new AddPrivilegesRoleRequest
{
RoleId = new Guid(“1A7F9E89-8283-E311-8E04-463500000031”),
Privileges = new[]
{
new RolePrivilege
{
Depth = PrivilegeDepth.Basic,
PrivilegeId = prv.Id
}
}
};
break;
}

case “prvWritecrmtr_testentity1”:
{
AddPrivilegesRoleRequest req = new AddPrivilegesRoleRequest
{
RoleId = new Guid(“1A7F9E89-8283-E311-8E04-463500000031”),
Privileges = new[]
{
new RolePrivilege
{
Depth = PrivilegeDepth.Local,
PrivilegeId = prv.Id
}
}
};
break;
}
}

}

1A7F9E89-8283-E311-8E04-463500000031 is the Guid of the marketing manager role. Looking at the code we find that we are using the AddPrivilegesRoleRequest to do the same. The code is pretty simple and self expalnatory. The access level is provided by the PrivilegeDepth enumeration.

Once the code oi executed we now have User level create and Business Unit level write on the Test Entity 1 for the Marketing Manager security role.

Image2

Hope this helps!

{Dynamics CRM} Not getting latest Text field value on click of custom ribbon button in CRM 2013

Recently in my project, I was faced with the above problem. The exact scenario is explained below.

I have a text field for entering the Device Id in CRM. The user enter a value in the textbox and clicks on the the ‘Determine 54-90’ custom ribbon button without tabbing out from the textbox as shown in the screenshot below.

Capture101

The problem is inside the function that is called from ribbon button click, the value obtained using Xrm APIs for this Device ID field does not reflect the latest value entered. This is because the user has not tabbed out from the field before clicking the ribbon button.

In CRM 2011, the following code during onload of the form would resolve the issue.

document.getElementById(“<controlid>”).onblur = function()
{
var latestValue = document.getElementById(“<controlid>”).value;
}

However the same code might not work in CRM 2013 because in CRM 2013, the rendering model has changed completely. On load of the form all the controls are loaded as div and the value of the control is shown inside the span of the Div.

The moment the user clicks on the text field, it becomes an input field. So the scenario would be:

1. if the user don’t tab out of the textfield, check for the latest field value using a jquery

2. If the user has tabbed out, get the value of the textfield using the XRM API

the code below achieves the same.

if ($(“input[attrname='[field_logicalname]'”).length > 0) {
           Xrm.Page.getAttribute(“[field_logicalname]”).setValue($(“input[attrname='[field_logicalname]'”).val());
}

 

Hope this helps!