Tuesday, 12 September 2017

Track Contacts in Dynamics 365 via Outlook App

Hi,

Today our customer said that Tracking of a contact via Outlook App is no more working. When I have tested, it is working. 

Had a screen sharing session with the customer and downloaded Fiddler on his machine and checked the calls. And found a call failed with 500 error code and here is the error message.

message=A validation error occurred.  The length of the 'emailaddress1' attribute of the 'contact' entity exceeded the maximum allowed length of '100'.

I checked the Contact in Outlook and Email Address field was crossing the limit and our customer gave some data just to check the tracking.

Unfortunately, the App won't the message to the user. It's not only Email Address field but any field that is crossing the limit will create the same.

Hope this helps.

--
Happy CRM'ing
Gopinath

Saturday, 9 September 2017

Connect to Dynamics CRM WebApi from Console Application

Hi,

I was hearing some requirement to connect to CRM Webapi from a console application. but never got a chance to really check. However, here are the steps that has to be foollwed and the code.

To connect CRM Web Api there are two steps.

1) Register the Application with the Azure Subscription
2) Build the Console Application to connect to CRM Web Api by using Client ID and Authority URL.

Just one thing to remember is the below process works if both CRM and Azure are under same tenant. If they are different tenant, we have to follow different process. Will try to write it next time.

Register the Application

1) Login to https://portal.azure.com and navigate to Azure Active Directory and click on New Application Registration button. 


2) Enter the Name (whatever you wish). You can use any name which should be unique in the App Registrations.
3) Selecte Application Type as Native as we are not building any WebApplicaton/Web Api.
4) Next is Redirect URL. This is something, AD will redirect once the Authentication is done. You can put anything in the following format as we are calling this from Console Application.

XXXXXXX://XXXXXX

Note this URL as we need this in the Console Application

5) Click on the Create button to Register the App. Once the App is registred, you will get the Application ID.

6) Go to the settings of the app -> Required Permissions -> Add -> Select an API -> Dynamics CRM Online -> Select

7) And in the same place, click on Select Permissions and select "Access CRM Online as organization users" and click on Select.


Please note down the following to use in the Console Application

1) Client ID - Which is an Application ID of the App
2) Redirect URL - The one which we gave in Step 4 from above

Console Application

1) Create a Console Application.
2) Add Microsoft.IdentityModel.Clients.ActiveDirectory dll reference. If you don't have that, get it from Nuget Package.

Here the complete code which you can copy and paste and make sure you change the Global Variables accordingly.

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;


namespace CRMWebApiConnection
{
    class Program
    {
        /// <summary>
        /// Holds the Authentication context based on the Authentication URL
        /// </summary>
        static AuthenticationContext authContext;

        /// <summary>
        /// Holds the actual authentication token once after successful authentication
        /// </summary>
        static AuthenticationResult authToken;

        /// <summary>
        /// This is the API data url which we will be using to automatically get the
        ///  a) Resource URL - nothing but the CRM url
        ///  b) Authority URL - the Microsoft Azure URL related to our organization on to which we actually authenticate against
        /// </summary>
        static string apiUrl = "https://abc.crm5.dynamics.com/api/data";

        /// <summary>
        /// Client ID or Application ID of the App registration in Azure
        /// </summary>
        static string clientId = "ec014b98-af68-48fc-9147-7928420c08d7";


        /// <summary>
        /// The Redirect URL which we defined during the App Registration
        /// </summary>
        static string redirectUrl = "my-Console://CRMConsole";

        static void Main(string[] args)
        {
            GetToken();

            Console.ReadLine();

        }

        internal static async void GetToken()
        {
            try
            {
                // Get the Resource Url & Authority Url using the Api method. This is the best way to get authority URL
                // for any Azure service api.
                AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(new Uri(apiUrl)).Result;

                string resourceUrl = ap.Resource;
                string authorityUrl = ap.Authority;

                //Generate the Authority context .. For the sake of simplicity for the post, I haven't splitted these
                // in to multiple methods. Ideally, you would want to use some sort of design pattern to generate the context and store
                // till the end of the program.
                authContext = new AuthenticationContext(authorityUrl, false);

                try
                {
                    //Check if we can get the authentication token w/o prompting for credentials.
                    //With this system will try to get the token from the cache if there is any, if it is not there then will throw error
                   // authToken = await authContext.AcquireTokenAsync(resourceUrl, clientId, new Uri(redirectUrl), new PlatformParameters(PromptBehavior.Never));
                    var userName = "XXXX@XXXX.onmicrosoft.com";
                    var password = "XXXXXXX";
                    UserCredential credentials = new UserPasswordCredential(userName, password);
                    authToken = await authContext.AcquireTokenAsync(resourceUrl, clientId, credentials);

                }
                catch (AdalException e)
                {
                    if (e.ErrorCode == "user_interaction_required")
                    {
                        // We are here means, there is no cached token, So get it from the service.
                        // You should see a prompt for User Id & Password at this place.
                        authToken = await authContext.AcquireTokenAsync(resourceUrl, clientId, new Uri(redirectUrl), new PlatformParameters(PromptBehavior.Auto));
                    }
                    else
                    {
                        throw;
                    }
                }

                Console.WriteLine("Got the authentication token, Retrieving data from Webapi");

                GetData(authToken.AccessToken);

            }
            catch (Exception ex)
            {
                Console.WriteLine($"Please see the exception details : {ex.ToString()}");
            }
        }

        internal static async void GetData(string token)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                httpClient.Timeout = new TimeSpan(0, 2, 0);  // 2 minutes time out period.

                // Pass the Bearer token as part of request headers.
                httpClient.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", token);


                var data = await httpClient.GetAsync("https://abc.crm5.dynamics.com/api/data/v8.2/accounts?$select=name");


                if (data.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    // If the status code is success... then print the api output.
                    Console.WriteLine(await data.Content.ReadAsStringAsync());
                }
                else
                {
                    // Failed .. ???
                    Console.WriteLine($"Some thing went wrong with the data retrieval. Error code : {data.StatusCode} ");
                }
                Console.ReadLine();

            }
        }
    }
}


Hope this helps.

--
Happy CRM'ing
Gopinath

Send Email to unresolved Recipients

Hi,

I was working some email functionality today and question came up saying can we send email to external people which are not part of Lead, Contact, Account or any CRM object.

An immediate answer from my mouth is No but some how my mind stopped and did a quick check and came to know that there is an option for that.

Settings -> Administration -> System Settings -> Email Tab - Allow messages with unresolved email recipients to be sent To Yes


Hope this helps.

--
Happy CRM'ing
Gopinath

Wednesday, 16 August 2017

'Cannot specify child attributes in the columnset for Retrieve' when Merging two Accounts in CRM

Hi,

Today, I was writing C# code for merging two accounts in CRM. For sometime, it was working fine and suddenly it started giving the below error.

Not sure, what happened. Just went back and checked the differences between then and now and understood that I have added couple of fields to the UpdateContent entity object and those are causing the issue.

After some search came to know it was happening because of lookup fields. Whenever, we added lookups field we have to make sure that the entityreference object should not contain value for Name property and we have to explicitly add name attribute to the UpdateContent object as below.

// Add EntityLogicalName + 'Name' property to UpdateContent object.
// updateContent.Attributes.Add("transactioncurrencyame", erfTransactionCurrencyId.Name);
updateContent.Attributes.Add(erfTransactionCurrencyMain.LogicalName + "name", erfTransactionCurrencyId.Name);
// Set the Name Property of the Look up object (Entity Reference) to Null.
erfTransactionCurrencyMain.Name = null;
// Add Lookup object (Entity Reference after setting Name value to Null) to the UpdateContent Object.
updateContent.Attributes.Add("transactioncurrencyid", erfTransactionCurrencyMain);


Hope this helps.

--
Happy CRM'ing
Gopinath

Monday, 14 August 2017

Value cannot be null.\r\nParameter name: identityProvider

Hi,

Today I got the below error while running an console application which retrives account details from CRM.

Value cannot be null.\r\nParameter name: identityProvider

And that code was working earlier, not sure what went wrong and started searching here and there.

Finally, came to know that there was an extra space in the UserName which I have given as an input for the application to connect to CRM. Removed the space and able to perform my task.

Note : There could be many other reasons causing this issue and this wrong username or extra characters is one of them.

Hope this helps.

--
Happy CRM'ing
Gopinath

Saturday, 12 August 2017

Field/Attribute is not visible to specify as a Alternate Key

Hi,

Today we are creating some of the alternate keys in the system for some integrations and observed one of the custom fields which we have created on Contact is not showing up in the Alternate Key list. 

Somehow wondered and checked the field. After checking the field, came to know that Field Security was enabled for it and after disabling it, the field is visible in the fields list of alternate key.

For double checking, added that field to the Alternate Key fields list and tried to enable to Field Security and received the error as below.



Also, it makes sense if we enabled to Field Security not all the users doesn't have read access and that way we are breaking the thumb rule of the Alternate Keys.

Hope this helps.

--
Happy CRM'ing
Gopinath

Tuesday, 8 August 2017

Create products in active state

Hi 

We have a requirement that Products are created in the CRM from integration and we know that first to use the products those should in Active state otherwise CRM will not show them in any product lookups.

We are thinking to ask Integration team to extend the design to set the status as Active once they creates Product. Just before checking, did some search and as always found an answer in a minute.

In CRM, we have setting which allows to create products in Active State.

Settings -> Administration -> System Settings -> Sales Tab -> Create products in active state -> Select Yes.

Note : This applies only to products without an associated product family.

Hope this helps.

--
Happy CRM'ing
Gopinath

Monday, 7 August 2017

Case option not available on Dynamics 365 Outlook App

Hi,

Today while working with new Outlook App suddenly observed that New Case option was removed from it. Little wondered and do not the reason.

After little search came to know that it was because of Read Only In Mobile user (settings -> customizations -> customize the system) was checked.

However, after enabling also it didn't work. Below are the things we should check.

1) Read only in Mobile user should be disabled.
2) Case entity must be selected for Global Search.

If it is not visible even after setting above, follow the below steps.

1) Open IE Browser -> Tools -> Internet Options
2) General Tab -> Delete -> Settings -> Caches and databases
3) As shown in the screen shot select Dynamics.com and click on Delete and then Ok button.
4) Restart your Outlook and you will new Case option now.

Hope this helps.

--
Happy CRM'ing
Gopinath

Saturday, 22 July 2017

Import Users to CRM

There are multiple ways to create new users in Dynamics CRM or Dynamics 365. We can use OOB import users as well.
Here are some of the key points which has to be followed via the Import Tool

1) For On Premise, User Name must have Domain name. Format - domain\user or user@domain.com format. For Online, Primary Email is mandatory
2) First Name and Last Name are mandatory.
3) All the users will be disabled in CRM.
4) We cannot set Business Unit during the import. By default, all users will be assigned to the Root business unit. After the import, we can update the business unit using Change Business Unit.
5) Every user will be assigned to Sales Person role by default.


Hope this helps.


--
Happy CRM'ing

Gopinath

Sunday, 4 June 2017

Workflow must be in Published State

Hi,

Suddenly, today our CRM instance starts showing below error on save of Lead record. We are pretty sure that there is no new changes on the Lead entity.

"Workflow must be in Published State"

After some analysis, checked the workflow error and it says some issue with SLA. We have a SLA on the Lead, I have de-activated and activated the same and able to save the record.


[Microsoft.Crm.Service.GlobalSlaPlugin: Microsoft.Crm.Service.GlobalSlaPlugin.SlaPostCreatePlugin]
[554f5c53-1941-e711-8129-c4346bad9624: ObjectModel Implementation]


Fix - De-activating and Activating the SLA configured on the repective entity fixes the issue.

Hope this helps.

--
Happy CRM'ing

Gopinath

Thursday, 20 April 2017

Organization Insights in Dynamics 365

Organization Insights for Dynamics 365 (online) provides important adoption and use metrics for your Dynamics 365 organization, and tools to help you stay ahead of performance and support issues.

Administrator can easily measure and identify the following things.

  • surfaced include charts that can measure and identify:
  • Active and Inactive users
  • Entities by number of records and storage usage
  • Storage by CRM Instance
  • Workflows that consistently fail, resulting in poor data quality and unexpected results
  • Plugins that may not be working as expected

By default the Organization Insight dashboards are only available to System Administrators and Customizers, but security roles can be updated to give ither users access.

Install and view the Organization Insights solution

If you are using a trial version of Dynamics 365 (online), you can install the new Organization Insights from AppSource

  • In Dynamics 365, from the main menu, click Settings > Dynamics Marketplace.
  • In the search box, type "organization insights".
  • When you see the Organization Insights app, click Try, and then Continue.
  • In the Add the application to Dynamics 365 dialog box, choose your organization.
  • Proceed through the terms of service and click Agree.
  • To verify that the solution is installed, go to Settings > Solutions. You will see Organization Insights in the list of solutions. (While the solution is installing, the status of the solution changes to "Installation pending". When it's installed and ready to use, the status will change to "Installed".)
  • To view the new Organization Insights dashboard, go to Settings > Organization Insights.
For more information, refter this Technet Article.

Hope this helps.

--
Happy CRM'ing
Gopinath