Archive

Posts Tagged ‘CRM’

(401) Unauthorized Error – CRM integration with SharePoint

December 12, 2017 2 comments

We encountered below exception when we were integrating CRM with SharePoint.

Exception: System.Net.WebException: The remote server returned an error: (401) Unauthorized.

Environment details:

  • CRM 2016 on-premise with Claims authentication enabled.
  • SharePoint Server On-premise with Claims authentication enabled.
  • User Account using to set up is Admin on both the CRM and Sharepoint servers.

Reason & Fix:

Fix suggested in this MSDN Forum worked for us.

It seems there is a known issue/bug with CRM 2016 that doesn’t allow this to work if you try using https in the MetadataEndPoint.

To get this working, you will have to temporarily do the following items before running the SharePoint Power Shell command.

Note : Make sure you note all the existing settings before executing below steps which helps you to roll back, if something goes wrong.

Steps:

  1. Open the CRM Deployment Manager tool
    • Disable CRM IFD
    • Disable CRM Claims Configuration
  2. Open the IIS and remove the https binding on the CRM Web site and add back the http binding for the CRM Web site.
  3. Run CRM Deployment Manager and change the properties of the deployment for the Web Address to use http instead of https.
  4. Run an IISReset on the CRM Server to ensure this is now accessible via http.
  5. Run the SharePoint PowerShell commands (you should be able to access the MetadataEndpoint using http vs. https now if you put it in the browser (and it should prompt to download a .json file).
  6. Once the SharePoint commands are finished running, you need to reverse the changes above in CRM to re-enable IFD.
  7. Change the CRM Web Address to use https in the CRM Deployment Properties.
  8. Remove the http binding on the CRM Web site and add back the https binding, selecting the correct SSL Certificate.
  9. Run the Configure CRM Claims in the CRM Deployment Manager.  (keep the existing settings)
  10. Run the Configure IFD in the CRM Deployment Manager (keep existing settings).
  11. Run an IISReset on the CRM Server.

Refer MSDN article  which details integrating SharePoint on-premise with CRM on-premise.

🙂

Advertisement

Set “Created On”,” Created By”, “Modified On”, “Modified By” fields using SDK/Data Import/Plug-in – Dynamics 365

November 18, 2017 Leave a comment

I got an ask from one of my blog followers on how to set “Created On” field of a record, as it defaults to current date.

In this article I am going to explain various ways to set these values.

Override ‘Created On’ using Data Import:

  • Using ‘Data Import’, setting the “Created On” is straight forward and all you need is to add a column “Created On” in your .csv file and import.

Override Created On - Data Import

  • For non-system admin users who import, make sure “Override Created on or Created by…” Privilege is checked in their Security Role.

Override Created On - Privilege

Points to Ponder:

  • Even though the privilege “Override Created on or Created by for records during data import” name suggests overriding “Created by” field but we cannot override “Created by” via Data Import.

Override ‘Created On’ using SDK:

  • Set the “overriddencreatedon” field to the date, which you want your “Created On” date as.
  • Post the execution of code, “Created On” value will be overridden with the Date set in “overriddencreatedon” field and “overriddencreatedon” field will default to todays date.
  • For example, today is “01-01-2017” and you want the “Created On” as “01-01-2016”
    • Set “overriddencreatedon” to “01-01-2016”
    • After code execution, “Created On” will set to “01-01-2016” and “overriddencreatedon” will be today (i.e., 01-01-2017)

Sample code:

Entity contact = new Entity(“contact”);
contact[“firstname”] = “Contact Migrated”;
contact[“overriddencreatedon“] = new DateTime(2016, 01, 01);
_service.Create(contact);

Override “Created On”,” Created By”,” Modified On”,” Modified By” using Plug-in:

  • To Override the fields, we need to go for plug-in approach.
  • Register a “PreOperationCreate” plug-in and set the fields.

Override Created On - Plug-in step

Plug-in Code:

public void Execute(IServiceProvider serviceProvider){
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains(“Target”) && context.InputParameters[“Target”] is Entity)
{
// Obtain the target entity from the input parameters.
Entity TargetEntity = (Entity)context.InputParameters[“Target”];

// Set date in Past
TargetEntity[“createdon”] = new DateTime(2016, 01, 01);
TargetEntity[“modifiedon”] = new DateTime(2016, 01, 01);
// Set the GUID of non-calling user
TargetEntity[“createdby”] = new EntityReference(“systemuser”, new Guid(“5BB6EF5F-6BCC-E711-A831-000D3A1BE051”));
TargetEntity[“modifiedby”] = new EntityReference(“systemuser”, new Guid(“5BB6EF5F-6BCC-E711-A831-000D3A1BE051”));
}
}

  • Once this plug-in executes, values will get overridden with the passed values.

Override Created On - Plug-in

Points to Ponder:

  • As you would have noticed, it requires a plug-in to set the ”Created By”,” Modified On”,” Modified By” fields which is an overhead.
  • But this approach is extremely useful in “Data Migration” as this is common ask while migrating historical client data.
  • Have the plug-in step enabled during “Data Migration” and deactivate post migration.

 

CRM Record “Email a Link” feature not working

February 8, 2017 Leave a comment

Recently few of our CRM users complained OOB “Email a Link” not working.

email-link

Reason:

  • Machines default “Email” App was set to “Chrome”

email-settings

Fix:

  • Change default “Email” App to “Mail” or “Outlook” client

 

email-settings-set-to-mail-client

🙂

Categories: CRM, Uncategorized Tags: , ,

Retrieve Global Option set details – CRM SDK

January 28, 2017 1 comment

Below is the sample code to retrieve existing Global Option sets along with Option text & values using RetrieveAllOptionSetsRequest :

var retrieveAllOptionSetsRequest = new RetrieveAllOptionSetsRequest();

RetrieveAllOptionSetsResponse retrieveAllOptionSetsResponse = (RetrieveAllOptionSetsResponse)orgService.Execute(retrieveAllOptionSetsRequest);

if (retrieveAllOptionSetsResponse.OptionSetMetadata.Count() > 0){
StringBuilder sb = new StringBuilder();
foreach (OptionSetMetadataBase optionSetMetadataBase in retrieveAllOptionSetsResponse.OptionSetMetadata){
if (optionSetMetadataBase.OptionSetType != null){
if ((OptionSetType)optionSetMetadataBase.OptionSetType == OptionSetType.Picklist){
OptionSetMetadata optionSetMetadata = (OptionSetMetadata)optionSetMetadataBase;
sb.AppendLine(“OptionSetDisplayName – ” + ((optionSetMetadata.DisplayName.LocalizedLabels.Count > 0) ? optionSetMetadata.DisplayName.LocalizedLabels[0].Label : String.Empty));
sb.AppendLine(“***************************************************”);

foreach (OptionMetadata option in optionSetMetadata.Options){
sb.AppendLine(“Option”);
sb.AppendLine(“OptionValue – ” + option.Value.ToString());
sb.AppendLine(“OptionDescription – ” + option.Label.UserLocalizedLabel.Label.ToString());
}
}
else if ((OptionSetType)optionSetMetadataBase.OptionSetType == OptionSetType.Boolean){
BooleanOptionSetMetadata optionSetMetadata = (BooleanOptionSetMetadata)optionSetMetadataBase;
// Start OptionSet Node
//metadataWriter.WriteAttributeString(“OptionSetType”, OptionSetType.Boolean.ToString());
if (optionSetMetadata.DisplayName.LocalizedLabels.Count != 0)
sb.AppendLine(“OptionSetDisplayName – ” + optionSetMetadata.DisplayName.LocalizedLabels[0].Label);
else
sb.AppendLine(“OptionSetDisplayName – ” + “UNDEFINED”);

sb.AppendLine(“**************************************************”);

// Writes the TrueOption
sb.AppendLine(“TrueOption”);
sb.AppendLine(“OptionValue – ” + optionSetMetadata.TrueOption.Value.ToString());
sb.AppendLine(“OptionDescription – ” + optionSetMetadata.TrueOption.Label.UserLocalizedLabel.Label.ToString());
sb.AppendLine(“FalseOption”);
sb.AppendLine(“OptionValue – ” + optionSetMetadata.FalseOption.Value.ToString());
sb.AppendLine(“OptionDescription – ” + optionSetMetadata.FalseOption.Label.UserLocalizedLabel.Label.ToString());
}
}
sb.AppendLine(string.Empty);
}

Console.WriteLine(sb.ToString());

Output would be

global-options-1

global-options-2

🙂

Categories: CRM Tags: ,

CRM Date and Time field – Behaviors

December 18, 2016 2 comments

Recently, I was asked a question in my blog on what is the significance of the different ‘Behaviors’ of ‘Date and Time’ field.

There are 3 different behaviors available for ‘Date and Time’ field.

Date and Time field behavior

Date and Time field behavior

User Local:

  • Time zone would be applied on this behavior. Field’s Date and time would be shown based on current user’s time zone.
  • ‘User Local’ behavior of a Field can be changed to other behaviors after field creation.
  • If the field behavior changed,
    • Behavior change takes affect only to the newly added/updated field values.
    • The existing field values remain in the database in the UTC time zone format.
  • To change the behavior of the existing field values from UTC to Date Only we would need SDK call (ConvertDateAndTimeBehaviorRequest)
  • Below is the sample code

var request = new ConvertDateAndTimeBehaviorRequest(){
Attributes = new EntityAttributeCollection() {
new KeyValuePair<string, StringCollection>(“account”, new StringCollection()
{ “new_sampledatetimeattribute” })
},
ConversionRule = DateTimeBehaviorConversionRule.SpecificTimeZone.Value,
TimeZoneCode = 190, // Time zone code for India Standard Time (IST) in CRM
AutoConvert = false // Conversion must be done using ConversionRule
};

// Execute the request
var response = (ConvertDateAndTimeBehaviorResponse)_serviceProxy.Execute(request);

 

    • Conversion rules:
      • SpecificTimeZone: Converts UTC value to a DateOnly value as per the specified time zone code.
      • CreatedByTimeZone: Converts UTC value to a DateOnly value that the user who created the record.
      • OwnerTimeZone: Converts UTC value to a DateOnly value that the user who owns the record.
      • LastUpdatedByTimeZone: Converts UTC value to a DateOnly value that the user who last updated the record
  • When you execute the ConvertDateAndTimeBehaviorRequest message, a system job (asynchronous operation) is created to run the conversion request.

Date Only:

  • Time zone isn’t applicable to this behavior. Field values are displayed without the time zone conversion.
  • The time portion of the value is always 12:00AM
  • This Behavior can’t be changed to other behavior types, once it’s set.
  • The Date Only behavior is good for cases when information about the time of the day and the time zone isn’t required, such as such as birthdays or anniversaries.

Time-Zone Independent:

  • Time zone isn’t applicable to this behavior. The field values are displayed without the time zone conversion.
  • This Behavior can’t be changed to other behavior types, once it’s set.
  • You can use this behavior when time zone information isn’t required, such as the hotel check-in time.

Refer MSDN article for more details.

🙂

Categories: CRM Tags: , ,

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”);

🙂

Categories: CRM Tags: , ,

System.Web.HttpUnhandledException – While opening a CRM record

Other day we were getting “Unexpected” exception while opening a ‘Contact’ record.

There were no error details to check at application level.

When I verified my CRM application server’s Event viewer, there was below error log

Exception of type ‘System.Web.HttpUnhandledException’ was thrown.

at System.Web.UI.Page.HandleError(Exception e)

at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Index was outside the bounds of the array.

Fix:

  • By resetting the IIS on CRM application servers solved the issue.

Reason:

  • Not sure what caused this exception, as nothing had been customized on Contact entity.

🙂

Host a SSRS report which gets data from external Data Source – CRM on-premise

January 7, 2016 3 comments

We got a requirement to host a SSRS report in CRM, which gets data from external data source (i.e., Data Base from another SQL server).

CRM normally uses Shared Data Source when you upload any SSRS report which pulls data from CRM.

In our case we had to

  • Create a new Data Source
  • Override the CRM Shared Data Source with a new Data Source

Below are the steps.

Develop and Deploy Report in CRM

  • Design the report with Data Source connected to external Database.
  • Preview and make sure you are getting data properly.
  • Save the .rdl
  • Open CRM application
  • Create a new report and upload the .rdl
Upload SSRS Report To CRM

Upload SSRS Report To CRM

Configure the Report’s DB Connection

Now we got report in CRM and we need to point the report to Custom DataBase by following steps below

  • Connect to the SSRS server
  • Open the browser and type (http://servername/Reports) (You can also get URL from “Reporting Services Configuration Manager à Report Manager URL” tab)
Reporting Service Config Manager

Reporting Service Config Manager

  • In the Home page, click on ‘New Data Source’
Create New Data Source - 1

Create New Data Source – 1

  • Provide the Connection String and Credentials and Save
Create New Data Source - 2

Create New Data Source – 2

  • Go back to the report server home page.
  • Open the folder by name (YourCRMORG_MSCRM)
  • Go to ‘CustomeReports’ folder and select your report (Refer ‘Description’ column for Report Name)
  • Choose Manage from context menu
Create New Data Source - 3

Create New Data Source – 3

  • Choose ‘Data Sources’ tab and select newly created ‘Data Source’
Select the Data Source

Select the Data Source

  • Click on ‘Apply’
  • Close and re-run the report to get the changes.

🙂

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

December 4, 2015 1 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: , , ,

Access Denied Error – Case Reactivation

October 22, 2015 Leave a comment

Recently we deployed a solution on Customer environment and few users complained of getting ‘Access Denied’ error message while trying to ‘Reactivate’ a resolved case.

Access Denied - Case Reactivation

Access Denied – Case Reactivation

Issue was intermittent and we were unable to reproduce in our Development environment.

After spending some time, we identified ‘Access Denied’ coming up only for Cases resolved by a set of Users.

Reason

  • CRM creates a new ‘Case Resolution’ activity upon ‘Case Resolve’ with Status ‘Completed’.
  • Upon ‘Case Reactivation’ it updates the existing ‘Case Resolution’ activity Status to ‘Canceled’.
Case Resolution Activity

Case Resolution Activity

  • Coming back to my scenario,
    • Our Security model, had BU level ‘Write’ access on ‘Activity’.
    • When ‘Case’ resolved by a ‘U1’ from Business Unite ‘BU1’, system created ‘Case Resolution’ activity with owner as ‘U1’.
    • When ‘U2’ from BU2, tries to ‘Reactivate Case’, system actually try to update status of ‘Case Resolution’ activity created by U1 of ‘BU1’.
    • Since Users only had BU level ‘Write’ access on Activity, U2 cannot update ‘Case Resolution’ activity, hence he got ‘Access Denied’ exception.

Fix

  • Elevated ‘Write’ access on ‘Activity’ from ‘BU’ to ‘Parent BU’

🙂

Categories: CRM Tags: , ,