Monday 29 May 2017

Mobile compatible development - formSelector - Microsoft Dynamics CRM - MoCA_Tip#2

After the MoCA wave with D365, we are rapidly evolving in mobile space. This evolution demands mobile compatible development and the same is our key to success.

I have planned to share my experience with MoCA as a series and the link for previous tips can be found at the end of this blog.

lets jump on to the tip now,

Its common to have Xrm.Page.ui.formSelector in our JavaScript development and the same is used to identify current form and for form navigation.

Xrm.Page.ui.formSelector is not supported in mobile!
In MoCA formselector is not available and usage of the same will result in form error. This is because mobile application doesn't have multiple forms. 

From MSDN Library:
Dynamics 365 for phones and tablets does not provide the capability to switch between forms. If you have more than one main form for an entity, the one displayed depends on the form order set and which security roles are assigned to the form.


Ways to overcome this issue,
  1. Preferred solution is to avoid using multiple forms 😉  - This may sound crazy, but its better to design the main form in a way that everything fits into it. This automatically streamlines all your form related development mobile compatible. 
  2. Another way is to conditionally avoid form selector piece of code by validating the client. If the client is mobile skip the specific portion of code, sample code snippet is as follows

if (Xrm.Page.context.client.getClient() != "Mobile")
{
    //Form selector code goes here

}


Don't forget to go through previous tips if you have missed,
  1. Document template Fix
  2. Hidden tabs and Mobile application organization settings

Happy learning!



Thursday 25 May 2017

MSCRM - Email Tracking token understanding and configuration

In this article we are going to understand the purpose, configuration and tracking of the Email tracking token.

What is tracking token and why we need it?

Whenever an email is sent via CRM, a tracking token is suffixed to subject line by default and it is used for email tracking and correlation purpose.

This helps in auto mapping/matching related conversations to the regarding object. If its turned off, then we may need to compare key words in subject, sender and receiver to find the best match and this results in reduced probability.

Example Tracking Token: CRM:00010001



Should we disable tracking token?

Sometimes tracking tokens may cause confusion around the subject of the mail and we may need to get rid of it . But disabling tracking token affects the accuracy of email tracking and its not recommended by Microsoft.

In such situations we can update the prefix to a more meaningful one, like

Examples:
  • TrakingToken:00010001
  • Tracking#00010001 
  • #00010001
Note from Microsoft website
Tracking tokens are the only supported correlation method that can be used when you use Dynamics 365 for Outlook connected to an SMTP server and send email to a non-Exchange recipient. In this situation, if tracking tokens are not enabled, then correlation events, such as the automatically creating records based on the regarding object, may not work.

The tracking token is configurable under Email tab in System Settings,

For more information refer below link - Old article but the content is perfect

Tuesday 23 May 2017

MSCRM - Retrieve more than 5000 records using FetchXML - Simplified



I was working on a piece of C# code to retrieve more than 5000 records using Fetchxml. This may get bit tricky, so tried to simply the same as much as possible in the below post.

By default an organization service can return only the first five thousand records and page details for the next set of records, if exists.

The result entity collection exposes a Boolean attribute called MoreRecords, it will be true if more records available else false.

If more records available then we need to use the combo of pagingcookie and page(pagenumber) to retrieve rest of the records.

**Do not forget to add {0} in fetchxml which is used to include page details in below code

Code Snippet:

        public List<Entity> RetrieveAllRecords(IOrganizationService service, string fetch)
        {
            var moreRecords = false;
            int page = 1;
            var cookie = string.Empty;
            List<Entity> Entities = new List<Entity>();
            do
            {
                var xml = string.Format(fetch, cookie);
                var collection = service.RetrieveMultiple(new FetchExpression(xml));

                if (collection.Entities.Count >= 0) Entities.AddRange(collection.Entities);

                moreRecords = collection.MoreRecords;
                if (moreRecords)
                {
                    page++;
                    cookie = string.Format("paging-cookie='{0}' page='{1}'", System.Security.SecurityElement.Escape(collection.PagingCookie), page);
                }
            } while (moreRecords);

            return Entities;
        }


Example:

            var fetch = "<fetch {0}>" +
                        "    <entity name='accounts' >" +
                        "        <attribute name='accountid' />" +
                        "        <attribute name='name' />" +
                        "    </entity>" +
                        "</fetch>";
            var accountCol = RetrieveAllRecords(service, fetch);



Friday 19 May 2017

C# - Null conditional operator - Null check with question mark to handle null reference exception

Hello All,

Its good to meet you with yet another exciting tip and this time its around C#. With C# 6.0 there are many handy features introduced when it comes to day to day development.

One such feature is  Null conditional operator. ?

Personally during c# development, I always felt that in C# we lack better null condition handlers and I had to develop my own extensions to handle the same. But the situation is upside down now and I am loving this new null conditional operator.

Lets go through a quick example with code snippet

Consider the following function where we are trying to replace a value in a string, here we handle null in a conventional way


        private string StringReplaceTest(string input)
        {
            if (input == null) return null;

            return input.Replace("1", "2"); 
        }

With the latest version, we got our handy way to handle the null's and below is the updated code,


        private string StringReplaceTest(string input)
        {
            return input?.Replace("1", "2"); 
        }

Hope this helps.

MSCRM - Retrieve optionset label - RetrieveAttributeRequest - optionsetmetada - C#


Hello All,

Below is a quick code snippet that can retrieve picklist label based on value,

private string GetOptionsSetTextOnValue(IOrganizationService service,string entityName, string attributeName, int option)  
     {  
       RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest  
       {  
         EntityLogicalName = entityName,  
         LogicalName = attributeName,  
         RetrieveAsIfPublished = true  
       };  
       RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)service.Execute(retrieveAttributeRequest);  
       PicklistAttributeMetadata attributeMetadata = (PicklistAttributeMetadata)retrieveAttributeResponse?.AttributeMetadata;  
       if (attributeMetadata == null) return string.Empty;  
       var currentOption = attributeMetadata?.OptionSet?.Options?.FirstOrDefault(x => x.Value == option);        
       return currentOption?.Label?.UserLocalizedLabel?.Label != null ? currentOption.Label.UserLocalizedLabel.Label : string.Empty;  
     }  

To know more on conditional operator  with question mark, please refer
http://exptechsolutions.blogspot.com/2017/05/c-null-conditional-operator-null-check.html

Null conditional operators are the question marks in the above c# code which is a cool functionality that helps to avoid clumsy if conditions.

Friday 12 May 2017

MSCRM - Microsoft Dynamics CRM BIDS Extension Setup has stopped working - Reporting authoring extension installer failure - windows 10



A quick tip to solve report authoring extension installation issue which results in installer crash. It was hard to find the root cause as error was not specific.

Tried multiple things such as compatibility mode, visual studio shell extension installation and many other workarounds and nothing worked. Finally found that the issue was with RunOnce registry key.

Note: The below solution should also fix "Setup cannot continue because there is a pending restart required. Restart the computer and then try running Setup again" error

Solution :
If we delete this registry key(back-up before delete),  the installer will work fine

Possible Registry Key Locations:
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
  • HKEY_CURRENT_USER\Software\Microsoft\Windwos\CurrentVersion\RunOnce
  • HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce
Refer:
https://support.microsoft.com/en-us/help/2004114/you-receive-the-following-error-when-you-install-microsoft-dynamics-crm-for-microsoft-office-outlook-installation-cannot-proceed

Friday 5 May 2017

MSCRM - Entity not available in post configuration

Hi All,

I have seen lot of queries around entity not available in post configuration(Activity feed configuration).

By default CRM doesn't refresh the post configuration entities, we need manually refresh to view the latest entities.

To manually refresh, hit the refresh ribbon button and it should solve the issue

MSCRM - FetchXML filter based on time and time zone


Recently came across a scenario where we had to query CRM and retrieve accounts based on UTC date. After a fair bit of research, came-up with a Fetch query that can retrieve records based on time and time zone filters.

The key part in querying is the ISO 8601 format to specify the date time with timezone.

In the below date, +00.00 stands for UTC Time Zone and we can use any timezone by modifying this part.
2017-05-05T22:03:19+00:00

Below is a sample fetchxml, which retrieve records with modifiedon greater than or equal to given UTC datetime.

Note: Use 'greater than or equal to' or 'lesser than or equal to' instead of 'on or before' or 'on or after'

 <fetch>  
   <entity name="account" >  
     <all-attributes/>  
     <filter type="and" >  
       <condition attribute="modifiedon" operator="ge" value="2017-05-05T22:03:19+00:00" />  
     </filter>  
   </entity>  
 </fetch>  

To filter time based on user's timezone remove the timezone part(+00:00) from the query and the sample will look like below,

 <fetch>  
   <entity name="account" >  
     <all-attributes/>  
     <filter type="and" >  
       <condition attribute="modifiedon" operator="ge" value="2017-05-05T22:03:19" />  
     </filter>  
   </entity>  
 </fetch>


Hope this helps!

Tuesday 2 May 2017

MS CRM - Xrm.Page.getAttribute("attribute").fireOnChange() - #JSTip4


Hello All,

In our Xrm clientside object we have an method called fireOnChange(),

Purpose and Usage:
Triggers onchange event of the specific attribute, which in turn triggers the JavaScript functions attached to it.

Scenarios
  • At times, based on business needs we may need to execute a JS logic pinned to field on demand, where this function comes handy.
  • Script updates to a field will not trigger onchange of that field. We can use this way to trigger onchange event of the field if needed. 
Example: 
In account form, we have address fields and on change of address fields there is a logic to populate shipping address. Now when we add a primary contact consider the address fields should be updated from contact address. In this scenario, using JS if we update address fields the shipping address functionality tied to address fields will not fire. This is where we need to use fireOnchange.

Code Snippet:
Xrm.Page.getAttribute("fieldname").fireOnChange()

MS CRM - A currency is required if a value exists in a money field. Select a currency and try again - #CRMTip



Hello All,

Good to be back with another quick tip regarding currency and money fields.

Many of us might have experienced issues with money and currency fields, In this post we are going to learn a best practice and fix for one of the money or currency issues

Error:
A currency is required if a value exists in a money field. Select a currency and try again

Steps to replicate:
Open an existing CRM record without currency value populated, now enter data into any of the money fields and you will experience the above error.

Root Cause:
Money fields are currency dependent and when the currency is empty, its obvious that money is invalid.

Quick fix:
Populate currency field and it will fix the issue.

Best practice:
Make sure that currency field is always populated during create/update via workflow/plugin. If any custom logic is used to select currency, default a currency if no match found.