Advertisements

Archive

Author Archive

[Dynamics On-Premise] Mailbox Error – Server does not support secure connections

November 12, 2019 Leave a comment

Other day while configuring ‘Mailbox’, we got ‘Server does not support secure connections‘ exception, while approving the Mailbox using ‘Approve Email’ button.

EmailBoax_1

Reason:

Fix:

EmailBoax_3

  • We can set the ‘Use SSL for Incoming/Outgoing Connection’ properties either by making an SDK call or by updating ‘EmailServerProfileBase’ table in DB.

EmailBoax_2

🙂

Advertisements

[Step by step] Basic Canvas app using Dynamics 365 as Data Source

November 8, 2019 Leave a comment

In this article, I am going to provide steps to build a basic Canvas app which uses Dynamics 365 (CDS) as Data Source.

If you are new to Power Apps, refer my blog on steps to get started.

The App we are going to build will have 3 screens.

  • Manage Contacts – Displays the list of Contacts using ‘Gallery’ control.
  • Create Contact – Creates a new Contact.
  • Edit Contact – Updates an existing Contact.

Create a new Canvas app:

  • Connect to the Power Apps portal and select the ‘Environment’.
  • Create a new ‘Canvas app from blank’.

PA_Env3

Connect to Dynamics 365 data source:

Now we have the blank App and as a first step, create a new data source by connecting to your D365 instance using ‘Dynamics 365’ connector.

  • Click on the ‘Data source’ tab.
  • Under the ‘Connectors’, select ‘Dynamics 365’ and choose the ‘dataset’.
    • ‘dataset’ is your Dynamics organization name.

PA_Env4

  • Next, under the ‘Choose a table’ pane, select the entities you would like to work with.
    • I’ve chosen ‘Contacts’ entity for this App

PA_Env5

  • Click on ‘Connect’
  • You should see the ‘Contacts’ table under ‘Data sources’ as below:

PA_Env20

Design ‘Manage Contacts’ screen:

Now we have ‘Data source’ ready and lets design our first screen.

  • By default the Canvas app will have a screen.
  • Rename the out of the box screen to ‘ManageContacts’
    • Providing appropriate name to the controls is a best practice.
  • As we need to display available ‘Contacts’ on the screen, select ‘Insert -> Gallery’ and choose ‘Blank Vertical’.
    • ‘Gallery’ is a grid kind of a control.

PA_Env6

  • Now we need to map ‘Contacts’ table to the Gallery.
  • Select the ‘Gallery’ and click on ‘Edit gallery’ icon.

PA_Env7

  • In the ‘Select a data source’ pane, select ‘Contacts’ table. Now the ‘Gallery’ gets mapped with ‘Contacts’ from Dynamics.

PA_Env8

  • To display the Contact details (i.e., Full Name, Email, etc…), add ‘Label’ controls to the ‘Gallery’ and rename the Labels with meaningful names.
  • Labels will not show anything until you map them with the Contacts field.
  • So, select the Label and in the ‘Text’ property, type ‘ThisItem.{field_Name}
    • To map, ‘Full Name’ of the Contact to a label, set ‘Text’ as ThisItem.’Full Name’

PA_Env9

Design ‘New Contact’ screen:

In the ‘Manage Contacts’ screen, we configured a ‘Gallery’ which displays all the Contacts. Now lets design a ‘New Contact’ screen.

  • Add a ‘New Screen’ and rename it.
  • To Create/Edit records, we need to add ‘Forms’ control
    • ‘Edit’ form: Use this to Create or Edit a record.
    • ‘Display’ form: Use this to display the record (Read-only).
  • So, lets add a new ‘Edit’ form to the screen and rename it to ‘formCreateContact‘.

PA_Env12

  • Next, we need to map the ‘formCreateContact’ to ‘Contacts’ Data source and then select and arrange the ‘Contact’ fields, which allows us to input and save.
    • Set the ‘DataSource’ property of ‘formCreateContact’ to ‘Contacts’
    • Click on the highlighted link and add the required columns and click ‘Add’.

PA_Env13

  • Next, we can rearrange the columns using ‘Move up’ and ‘Move down’ options.

PA_Env14

  • We can also set ‘Columns’ to 1 of the ‘formCreateContact‘ which arranges the fields in a single column.
  • Add ‘Save’ icon to the ‘CreateContact’ screen.

PA_Env16.PNG

  • As we need to save the ‘Contact’ (i.e., Submit the Form) on ‘Save’ icon click, add below statement

SubmitForm(formCreateContact);

Link ‘Manage Contacts’ screen and ‘New Contact’ screen:

Now, we have the ‘New Contact’ screen ready. Lets hook it up to ‘ManageContacts’ screen.

  • Go to ‘ManageContacts’ screen and add + icon.
  • There are 2 key steps to create a new Contact
    • First create a new form of type ‘formCreateContact’.
    • Navigate to ‘New Contact’ screen.
  • We need to execute these key steps on click of + icon.
  • Select the + icon and on the ‘OnSelect’ event, add below statement

    NewForm(formCreateContact);Navigate(CreateContact);

PA_Env15.PNG

  • That’s it, run the App and you should be able to see the Contacts on ‘Manage Contact’ screen.

PA_Preview1.PNG

  • Click on + icon, which will take you to ‘New Contact’ screen.

PA_Preview2

  • Lets see ‘Edit Screen’ and Navigation’s in next article.

🙂

 

Categories: CRM, PowerApps Tags: ,

ADX Portals – Cannot register for ‘OnSendingHeaders’ event

November 5, 2019 Leave a comment

Other day, while configuring portal on a new CRM instance, portal shown error page, up on clicking the ‘Apply’ button.

License_Error1

There were no details on error screen to deduce the reason. So we had to go to the server where our portal website hosted.

When checked the ‘Event Viewer’ logs in Portal server, there was this following exception:

Exception type: InvalidOperationException

Exception message: Cannot register for ‘OnSendingHeaders’ event after response headers have been sent.

Reason & Fix:

  • CRM instance was missing ‘Adxstudio License Key’ record.
  • Post CRM connection, ADX would first check for the valid ‘License Key’. Since there was no ‘License Key’ record, Portal thrown error.
  • To fix this, add the ‘License Key’ by going to ‘Advanced Find -> ADXStudio License Keys‘, add a key.

License_Error2

🙂

 

D365 Integration – Handling concurrent transactions

October 26, 2019 Leave a comment

In one of our integration requirements, we got to make sure that there wont be any concurrent updates/deletion to the records, to avoid data loss.

As an example, lets assume a Record 1 was retrieved by users U1 and U2 and both want to update ‘Name’ field same time, in this scenario it could end up with either U1 or U2 overriding each others data.

In such scenarios we can prevent the data loss using Optimistic Concurrency.

Whats an ‘Optimistic Concurrency’?

  • This feature provides the ability for your applications to detect whether an entity record has changed on the server in the time between when your application retrieved the record and when it tries to update or delete that record.
  • If you notice, every entity will have an OOB field ‘VersionNumber’ of type ‘Time Stamp’.
  • ‘VersionNumber’ value gets updated by system, every time when the record updates.

Concurrency_4

  • In below screen, my record ‘Transaction’ has the ‘Name’ set to ‘Payment to UBER‘.

Concurrency_5

  • Let me retrieve the record and before triggering update, let me update the ‘Name’ field to ‘Payment to UBER_Updated‘.
  • Now the Update fails with error code.

Concurrency_3

  • The update would go through, if there wont be any updates post retrieve.

C# Code snippet:

var queryTransaction = new QueryExpression(“raj_transaction”){
ColumnSet = new ColumnSet(“versionnumber”, “raj_name”)
};

var transactions = _service.RetrieveMultiple(queryTransaction);

foreach (var transaction in transactions.Entities){
// transaction.RowVersion

// Update Name
transaction[“raj_name”] = DateTime.Now.ToString();

//Update the account
var request = new UpdateRequest()
{
Target = transaction,
ConcurrencyBehavior = ConcurrencyBehavior.IfRowVersionMatches
};

try{
_service.Execute(request);
}
catch (FaultException<OrganizationServiceFault> ex){
switch (ex.Detail.ErrorCode){
case -2147088254: // ConcurrencyVersionMismatch
case -2147088253: // OptimisticConcurrencyNotEnabled
throw new InvalidOperationException(ex.Detail.Message);
case -2147088243: // ConcurrencyVersionNotProvided
throw new ArgumentNullException(ex.Detail.Message);
default:
throw ex;
}
}
}

Notes:

  • Optimistic concurrency is supported on all out-of-box entities enabled for offline sync and all custom entities.
  • You can determine if an entity supports optimistic concurrency by retrieving the entity’s metadata using code or by viewing the metadata using the Metadata Browser IsOptimisticConcurrencyEnabled is set to true.
  • Refer my older article on Optimistic concurrency using WEB API in client script.
  • Refer article for more details.

🙂

Categories: CRM Tags:

D365/CRM – Document Template – Missing entity relationship

Other day, I was configuring a ‘Document Template’ for a custom entity (Acknowledgement) which has a 1:N Relationship with Contact entity.

DocTemp_1

For some reason, the Relationship was not showing up in the ‘1:N Relationship’ grid of the ‘Document Template’ configuration screen.

DocTemp_2

Reason & Fix:

  • The relationship ‘Searchable’ field was set to ‘No’ and hence it was not showing in the list.
  • Set the ‘Searchable’ field to ‘Yes’ and publish.

DocTemp_3

  • Refresh the Document Template’s ‘1:N Relationship’ grid and you should see the relationship now.

DocTemp_4

🙂

Categories: CRM Tags: ,

CRM (on-prem) – Entity reference cannot have Id and Key Attributes empty error

We encountered below exception from a custom workflow activity in our Dynamics CRM on-prem 8.2.3 application.

WF_Error1

Reason and Fix:

  • Error message states that the ‘Output’ argument defined in custom workflow activity was returning ‘Null’.
  • I have below output argument of type ‘Lookup’ defined in my custom workflow activity but it always having value.

WF_Error3

  • Error was misleading in our case, as our debug concluded that the Output argument was always having value.
  • After spending considerable time, we figured out that the issue was due to a change at CRM website level.
  • Our IT team enabled SSL and added https binding to our dynamics website which caused this issue.
  • We had to set the custom workflow assemblies Isolation mode to ‘Sandbox’ to get the workflow running.

WF_Error2

Note:

  • This issue occurred only on UAT server but not on DEV instance, which also had SSL enabled same time.
  • Issue could be due to security policies enabled between the CRM application server and platform server on UAT.

🙂

Categories: CRM Tags: ,

Web Development – Useful jQuery Syntax’s

In this article, I am compiling the useful jQuery syntax’s which comes handy during your Dynmaics/ADX portal development or any other web development.

Prerequisite

  • Add jQuery library to your web page using <script> tag.
  • You can get the jQuery CDN here

Get Operations:

  • Get HTML element by Id

$(“#HTMLelementId“)

  • Get element by Class name

$(“.ClassName“)

  • Get element by ‘partial’ Id name.
    • As an example, if you want to get a Checkbox control which has ID ‘myChkBox‘, you can either get the element using full id with $(“#myChkBox”) or use partial id $(“[id$=’ChkBox‘]”).

$(“[id$=’PartialId‘]”)

  • Get Value

$(“#HTMLelementId“).val()

  • Get selected drop down text

$(“#DropdownId option:selected”).text()

Set Operations:

  • Set Text box

$(“#HTMLelementId“).val(“Hello World”);

  • Set Checkbox

$(“#checkboxId“).prop(“checked”, true); //true is checked; false is unchecked.

Add or Remove Class

  • $(“#HTMLelementId“).addClass(“YourClassName“); // Add Class
  • $(“#HTMLelementId“).removeClass(“YourClassName“); // Remove Class

Hide/Show Element

  • Hide element

$(“#HTMLelementId“).hide();

  • To hide Parent
    • This is useful to hide a control along with Label.

$(“#HTMLelementId“).parent().hide()

  • Show element

$(“#HTMLelementId“).show();

Check if elements exists

if ($(“#HTMLelementId“).length > 0){}

Iteration syntax

  • Loop through all Radio boxes which set to False.

$(“input[id][type=’radio’][value=’0′]”).each(function () {
var radioBox = this;
});

Attach events to HTML elements

  • To add ‘keypress’ event to Text box

$(“#HTMLelementId“).on(“keypress”, keyPressHandler);

function keyPressHandler(){
// Read the textbox value
var controlValue = this.val();
}

Remove event handler

  • To remove ‘onChange’ event from a control use ‘unbind’ method.

$(“#dropDownID“).unbind(“change”);

Trigger event

  • To trigger button ‘Click’ event

$(“#ButtonId“).click();

Remove option from Drop down:

  • Below script, removes ‘Mango’ from the Drop down control.

jQuery(“#dropdownId option:contains(‘Mango’)”).remove();

Read Query String Parameter

  • To read ‘country’ param value from current URL http://helloworld?country=India, call getParamValue(‘country’)
  • Function will return false, if no matching param found.

function getParamValue(paramName) {
var results = new RegExp(‘[\?&]’ + paramName + ‘=([^&#]*)’)
.exec(window.location.search);

return (results !== null) ? results[1] || 0 : false;
}

Get/Set elements in IFrame

  • To Get or Set the values of elements in IFrame, below is the syntax.

$(“#YourIframeID“).contents().find(‘#txtBoxId‘).val(); // Get the value

$(“#YourIframeID“).contents().find(‘#txtBoxId‘).val(“Hello World”); // Set the value

  • To access IFrame with in another IFrame

$(“#Iframe1ID“).contents().find(“#Iframe2ID“).contents().find(‘#txtBoxId‘).val(“Hello World”);

Create a new element:

  • Below is the snippet to create HTML button and add that next to an existing HTML element.

$(‘<input type=”button” id=”newBtn” class=”Your class name” value=”My New Button”/>’).insertAfter($(“#existingHTMLElementId“));
$(“#newBtn”).click(function () {

// Write your onclick script here
});

Categories: ADX, CRM Tags: , ,