Fiddler for Model Driven Apps

While developing ‘PowerApp Components’ and traditional ‘Web Resources’, a common challenge is that testing is not straight forward. To test a change in HTML or JS code, one needs to deploy files, which is time-consuming. There are commercial tools available for model-driven apps to make it simpler but still using Fiddler have advantages. This first post of this series will explain how it works and how to get started with it.

What is Fiddler ?

Fiddler is a web proxy debugging tool often used by web developers. Basic version which we need is free forever and can be downloaded from here.

How does it work?

First, we add a web resource shell in the model-driven app, so if it JS, a file with just function name is fine. We still need to configure that function to trigger on load or save events in form properties. From this point to on we can start using Fiddler. We code in Visual Studio, configure Fiddler and open model-driven app in a browser. Fiddler will interrupt incoming request and replace JS file coming from cloud with file open in Visual Studio. Do a code change, just refresh and see the latest JS change without deploying it in app.

Benefits

  1. We can test JS/ HTML code without deployment. Do code change in Visual Studio, refresh your browser and verify changes.
  2. One can debug or develop without affecting other developers or users. Complete your work and when done deploy for testing.

Steps

  • Add web resource to model-driven app if it is a new resource. For details about web resources see this link and links under “See Also” section of it.
  • Install Fiddler
  • From Fiddler > Tools > Options > HTTPS, do the following:
    • Ensure “Capture HTTPS CONNECTs” and “Decrypt HTTPS traffic” are checked
    • In drop down “…from browsers only” is selected
    • “Certificates generated by” has “CertEnroll engine”
    • Click “Actions > Reset Certificates” and accept all prompts

  • Under Filters tab do the following configurations, these will help in targeting only relevant requests:
    • “Use Filters” check box is checked
    • Ensure for “Hosts”, “Show only Internet Hosts” is selected
    • Add your app URLs
    • “Show only if URL contains” is checked and it has “/webresources/”
  • In “AutoResponder” tab, do the following configs. Here we are telling which web resource we are working and what is the location of development version:
    • “Enable rules” is checked
    • Click Add Rule
    • Enter regular expression with name of JS file like “regex:(?insx).+/account.js”
    • Enter path to development version of file on local disk
    • Press save button
    • Ensure rule created is enabled
  • Check “Capture Traffic” under file menu:
  • Refreshing browser Fiddler should start capturing traffic. If we open the browser’s dev tools we can see code changes reflected without deploying them.

I hope it was helpful.

Querying Audit History

Audit history is a great out of box feature in model-driven apps. However, querying audit history is a bit tricky. Unfortunately commonly used querying mechanisms like Power Automate CDS connectors, LinQ, or simply FetchXml doesn’t support it. This post will discuss options we have and sample code for it.

Options

  1. Using SDK messages, RetrieveRecordChangeHistoryRequest & RetrieveRecordChangeHistoryResponse, covered in this post 
  2. Using Kingswaysoft’s Integration Toolkit for D365 (not covering in this post)

Scenario

I will query audit history for contact entity records and read audit details for its email address attribute. Audit details are available under these four heads:

  • Changed date
  • Changed field
  • Old value
  • New value

If auditing is enabled, this code will work for almost any entity and attributes.

How it works

We need ids (GUID) of entities and using those we will query audit history. I m using a fetchxml query to retrieve ids, but it can be mechanism of your choice depending on implementation and requirement.

       var targetEntites_query = @"<fetch {0}>
                                <entity name='contact'>                               
                                 </entity>
                                 </fetch>";     

Generally we know FetchXml can return maximum 5000 entities, but this code will handle and return even if there are more then 5000 records in the result.

public List<Entity> RetrieveAllRecords(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 = CrmClient.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;
        }

Tip: FetchXml query must have {0} if query will return more then 5000 records. Additional columns can be added in fetch if required.

Next, I m looping through these ids and read audit history for records using this code:

 public AuditDetailCollection GetAuditHistory(string entityLogicalName, Guid recordId)
        {           
            var changeRequest = new RetrieveRecordChangeHistoryRequest();
            changeRequest.Target = new EntityReference(entityLogicalName, recordId);
            var changeResponse = (RetrieveRecordChangeHistoryResponse)this.CrmClient.Execute(changeRequest);             
            return changeResponse.AuditDetailCollection;
        }

Above function returns AuditDetailCollection which has a collection of AuditDetails. One Audit detail represents one entry in audit history. Please note audit history records are in the same order as they appear in UI (descending).

Every audit details record will have a changed date, and collection of new and old values with field names which we will need to loop through and read.

Below is code to accomplish this:

             //Collection of entities for which we are going to read audit history
            var AllTargetEnteties = this.RetrieveAllRecords(targetEntites_query);


            foreach (var targetComplaint in AllTargetEnteties)
            {
                //Now pass id(guid) of record with entity name to retrieve audit history 
                var audit_history_entries = this.GetAuditHistory(targetComplaint.LogicalName, targetComplaint.Id);


                foreach (AuditDetail auditDetail in audit_history_entries.AuditDetails)
                {

                    if ((auditDetail.GetType())?.Name == "AttributeAuditDetail")                     
                    {
                        //Below code reads Changed Date
                        var changeDate = auditDetail.AuditRecord.GetAttributeValue<DateTime>("createdon");

                        var newValueEntity = ((AttributeAuditDetail)auditDetail)?.NewValue;
                        if (newValueEntity.Attributes.Count > 0)
                        {
                            {
                                foreach (var attrNewValue in newValueEntity?.Attributes)
                                {
                                    //Here we will need to match attribute name to read new value.
                                    //In this case I m reading emailaddress1
                                    if (attrNewValue.Key == "emailaddress1")
                                    {                                        
                                        var newEmailAddress = attrNewValue.Value;
                                        //Custom Logic for New Value here

                                    }
                                }
                            }
                        }


                        var oldValueEntity = ((AttributeAuditDetail)auditDetail)?.OldValue;
                        if (oldValueEntity.Attributes.Count > 0)
                        {
                            foreach (var attrOldValue in oldValueEntity?.Attributes)
                            {
                                //Here we will need to match attribute name to read old value.
                                //In this case I m reading emailaddress1
                                if (attrOldValue.Key == "emailaddress1")
                                {
                                    var oldEmailAddress = attrOldValue.Value;
                                    //Custom logic for Old value will be here

                                }
                            }

                        }

                    }
                }
            }

Let’s Connect

 twIcon lnIcon fbicon

Set Lookup Field in Java Script

Adding this post for someone who needs it and for my own reference.

In Java Script lookup can be populated in one of three ways depending on requirements:

  1. Query lookup data to set in form
  2. Get lookup details from data available in form (from other fields)
  3. Hard code lookup values

This is example using second option. It uses logged in user’s id and name to populate lookup. A lookup can be populated by providing its id (GUID) , name and entity type.

var approver = new Array();
approver[0] = new Object();
approver[0].id = Xrm.Page.context.getUserId(); // Guid as "{a004b16f-4bae-4445-9b15-438449a170d3}"; 
approver[0].name = Xrm.Utility.getGlobalContext().getUserName();
approver[0].entityType = "systemuser";
Xrm.Page.getAttribute("sofhof_approvedby").setValue(approver);

I hope it is helpful.

Let’s Connect

 twIcon lnIcon fbicon

Accessibility Resources

Accessibility is an essential consideration for a public sector or enterprise implementation. In this post I m sharing some resources generally about accessibility and also particularly about accessibility in Power Platform Projects. Some of the resources are from Microsoft and others are links to the work I have been doing in previous years. While preparing this list I m feeling very hopeful and excited, why ? because few years back there were not many resources available but now we have good collection, isn’t great 🙂

Resources

  1. Accessibility Fundamentals learning path at Microsoft Learn
  2. I presented ‘Accessibility in Power Platform Projects’ at Scottish Summit, here is link to recording
  3. Similar to above another session at our own “The Good Citizen Developers”, here is recording.
  4. In Oct 2020 I presented “Accessibility in PowerApp Projects” at Washington DC – User Group. Thanks to lovely organizers and supporters of UG Kylie KiserAiden KaskelaNelson JohnsonMike Ochs and others. I covered things like what accessibility is, why it is important and how to make a PowerApp project accessibility compliance. Here is recording https://www.youtube.com/watch?v=GdK2eV8oOLU
  5. Microsoft Accessibility Conformance Reports can be downloaded from here
  6. My blog posts on accessibility:

    “Accessibility” for D365 Projects
    “Accessibility” for D365 Projects 2
  7. Scottish Summit 2021 accessibility sessions

Let’s Connect

 twIcon lnIcon fbicon

XrmToolBox 2FA Authentication and Proxy Server Settings

2FA Authentications

When connecting XrmToolBox to an environment where 2FA is enabled, the following error can occur:

Error: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.

I found this issue when I started working on a new project and didn’t realise 2FA is enabled. Thankfully found Nishant Rana’s post that gave me hint.

Solution ?

Log in using “SDK Login Control” instead of “Connection Wizard” and follow these instructions.

and in next window select your D365 CE instance.

Proxy Settings

In environments where proxy server is placed, again XrmToolBox might not connect. To setup XrmToolBox with proxy server navigate to:
Configuration > Settings > Proxy

If Proxy configurations are set in IE “Use Internet Explorer Configured Proxy” option can be selected. Otherwise, choose “Use custom proxy” and complete the configurations with your proxy server details.

I hope you will find these tips helpful

Let’s Connect

 twIcon lnIcon fbicon

Binding CDS Data using Knockout (more tips)

This post is second in a series of querying CDS entity data and displaying it in a model-driven app web resource. A few days back, I wrote first post in this series CDS Data Binding using Knockout. Here I m answering a couple of questions and sharing a few more tips.

Though I have fetched data using WebApi and J-Query but any mechanism that returns object array will work. Yes, we can use FetchXml for querying data too.

The second thing is we can query data from multiple related entities using expand oData function. In this scenario, query returns cases with customer details. Customer can be an account or a contact:

var query = "/api/data/v9.1/incidents?$select=title&$expand=customerid_account($select=name),customerid_contact($select=fullname)";

While doing data binding a few times, I got an error:

Cannot ready property ‘name’ of undefined

The reason was in data few records don’t have customerid_account (parent object was null). To solve this, I have used if binding (Knockout offer different bindings) which checks and only bind the data if the object is not null.

<td>
<!--ko if:customerid_account -->
  <span id="accountNamee" data-bind="text:customerid_account.name"> </span>
<!--/ko-->
</td>

Knockout ‘with’ binding can also be used for this:

<td>
 <!--ko with:customerid_contact -->
         <span id="contactName" data-bind="text:fullname"></span>
 <!--/ko-->
</td>

We can do few tricks by using if and ifnot (else) bindings too. Query above is perfect example we either have customerid_account or customerid_contact not both. My requirement was to display combined data from both fields as one:

Here is complete sample code:

<!DOCTYPE html>
<html>
<head>

    https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js
    https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js
    http://../../../ClientGlobalContext.js.aspx
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <script>
        $(document).ready(function () {           
            var query = "/api/data/v9.1/incidents?$select=title&$expand=customerid_account($select=name),customerid_contact($select=fullname)";
            var oDataUrl = top.Xrm.Page.context.getClientUrl() + query;
            var _data = null;

            $.getJSON(oDataUrl)
                .done(function (data) {
                    if (data != undefined && data.value.length > 0) {
                        ko.applyBindings(new AppViewModel(data));

                        debugger;
                    }
                })
                .fail(function (error) {
                    debugger;
                });

        });


        function AppViewModel(data) {


            var self = this;
            self.Results = ko.observableArray([]);

            ko.utils.arrayForEach(data.value, function (d) {

                self.Results.push(d);

            });

        }



    </script>
</head>
<body>

    <div style="overflow-x:auto;">
        <h4 class="text-center">List of Cases</h4>
        <table id="tblContainer" class="table table-sm table-striped table-hover table-borderless">
            <thead>
            <th>Title</th>
            <th>Account</th>
            <th>Contact</th>
            <th>Client</th>
            </thead>

            <tbody data-bind="foreach: Results">
                <tr>
                    <td><span id="title" data-bind="text:title"></span></td>
                    <td>
                        <!--ko if:customerid_account -->
                        <span id="accountNamee" data-bind="text:customerid_account.name"></span>
                        <!--/ko-->
                    </td>

                    <td>
                        <!--ko with:customerid_contact -->
                        <span id="contactName" data-bind="text:fullname"></span>
                        <!--/ko-->
                    </td>
                    <td>
                        <!--ko if:customerid_account -->
                        <span id="accountNamee" data-bind="text:customerid_account.name"></span>
                        <!--/ko-->
                        <!--ko with:customerid_contact -->
                        <span id="contactName" data-bind="text:fullname"></span>
                        <!--/ko-->
                    </td>


                </tr>
            </tbody>
        </table>

    </div>


</body>
</html>

I hope you find this useful.

Let’s Connect

 twIcon lnIcon fbicon

CDS Data Binding using Knockout

In this post, I am explaining how to query data from a CDS entity and use Knockout to bind it in a model-driven app web resource. It has the following advantages:

  1. It is easy don’t require a lot of efforts (less coding)
  2. We have the flexibility to do further customisation

About demo:

Since it is demo, I have included script and link references from CDN. The focus of this post is to explain and share sample code for data binding. I m loading my web resource as a popup and have used AlertJS‘s free version for this. To keep this post short, I m not explaining how to add a button in Model-Driven App. But to summarise steps I have added JS file in my form, customised ribbon and added a button with the following code.

"use strict";
///<reference path="../mag_/js/alert.js">
var Account = (function ()
{
	return {
		LoadAccountsPopup: function (executionContext)
		{   
            Alert.showWebResource("webresource_accounts");			 
		}
	}
})();

In my web resource, I m getting data using Web API query. Data binding is done of course using Knockout and have used Bootstrap for styling. Here is code:

<!DOCTYPE html>
<html>
<head>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js" type="text/javascript"></script>
    <script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <script>
        $(document).ready(function () {
            var query = "/api/data/v9.1/accounts?$top=22&$select=name,telephone1,address1_city";
            var oDataUrl = parent.Xrm.Page.context.getClientUrl() + query;          

            $.getJSON(oDataUrl)
                .done(function (data) {
                    if (data != undefined && data.value.length > 0) {
                        ko.applyBindings(new AppViewModel(data));

                        debugger;
                    }
                })
                .fail(function (error) {
                    debugger;
                });

        });
        function AppViewModel(data) {
            var self = this;
            self.pingResults = ko.observableArray([]);
            ko.utils.arrayForEach(data.value, function (d) {
            self.pingResults.push(d);
            });
        }
    </script>
</head>
<body>

    <div style="overflow-x:auto;">
        <h4 class="text-center">List of Accounts</h4>
        <table id="tblContainer" class="table table-sm table-striped table-hover table-borderless">
            <thead>
            <th>Account Name</th>
            <th>Telephone</th>
            <th>City</th>

            </thead>

            <tbody data-bind="foreach: pingResults">
                <tr>
                    <td><span id="fileName" data-bind="text:name"></span></td>
                    <td><span id="fileType" data-bind="text:telephone1"></span></td>
                    <td><span id="fileType" data-bind="text:address1_city"></span></td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

I hope you find this helpful. If you have a question please leave me a comment on my blog and I will try to assist.

Enjoy your day.

Let’s Connect

 twIcon lnIcon fbicon

Power Chat with Olena Grischenko

Based in Sydney Australia Olena is a Microsoft MVP, developer and architect. She has vast experience in software development, D365 CE and Power Platform. She is a community speaker and organiser of multiple user groups.

Tell us about yourself (experience, background, industries, community service, else)

Started as a .Net developer, I’ve been working in IT for 20 years. Have worked with all versions of D365 CE and portals. As a part of my role, I do hands-on development, integration and architecture. I also do no-code development where required. Tried multiple times to give up “coding” for more manager type of roles but was always coming back. Started working as an independent consultant last October then launched a company with my partner in January. My favourite industry is higher education. Most of my projects are free community activities. I organise BizApps Women NSW, #PowerLabs and Microsoft 365 Pro-Low-No-Code Devs user groups. Also, I’m in the committee for Dynamics 365 UG NSW.

For the success of a Power App or D365 CE project, what are a few things (practices or steps) you do when kick-starting a new project?

Making sure this project is not set to failure from the beginning, and I’ve got a real power to make things happen by putting my effort and knowledge into it.

What delivery methodology you have found useful in projects?

Some people would say “it depends”. This is how I would like to answer too. But the truth is I am a true SCRUM believer. I had the opportunity to work with the most fantastic coach for SCRUM for Dynamics 365, Neil Benson, in one of the most successful implementations in my entire professional career.

What is one thing that can make a project successful or vice versa?

For me, the success of a project from the beginning of a project is very much predefined by a desire of key stakeholders and other key parties involved for the project to succeed. 

If people were forced to a change and they don’t believe this is the best way to go the rest of it is just a waste of their and your time. It’s tough to be a part of something which is doomed from the beginning. Unfortunately, it happened to my team and me before, and it’s a very traumatic experience.  

Give me two (or more) tips that will enhance the performance of my applications?

Don’t overthink or overcomplicate things, use the latest frameworks and SDKs which are up-to-date with security and performance updates. Make sure you understand the pros and cons of different approaches. Don’t have a solution, have more than one, understand the benefits of each.

Tell us two things (or more) which will improve the quality of deliveries?

Having a good team. Staying connected with a business and getting constant feedback.

In the context of D365 CE implementation, what does architecture means to you?

In terms of a SCRUM delivery architecture is not something predefined and one of. For me, it means it should be reviewed regularly to check if thigs we developed earlier make sense still.

What few things you consider when you are architecting or designing a solution?

Costs, licencing, maintenance and support. Scalability to a degree. I am not against “temporary” solutions, everything is temporary, but you should be aware of the price your customer is going to pay in the future.   

Tell us anything that you consider is/are the best practice(s) and everyone should follow?

There is no such thing as common sense so I can’t answer this question properly.

Share a tip of yours to boost productivity as a dev, consultant or architect?

Stay focused. Find a balance of a customer-facing and quiet time to concentrate. Both sides are crucial for a good consultant. Listen and hear.   

Tell us about a canvas app that you have built or seen which was awesome?

The most amazing ones are those built by end-users. Because they help them to solve their day to day problems.

Have you seen an impressive AI application recently, preconfigured or custom which you want to mention?

I believe that the most amazing applications are still in the future. We have to make sure it’s inclusive in all possible ways.

How you analyse and build security in projects? Any tips?

Not leaving to the very end of a project?

While doing configurations, do you follow some rules or practices?

There are too many of them.

Managed or Unmanaged?

Should I say “it depends” again “? Managed – for boxed products and unmanaged – for service projects and framework type of products. It may change or even it WILL change in the future, but for me it still the rule I follow.

Early bound or late bound?

Don’t like early bound. I know it’s a bad answer, wrong even.

LINQ, FetchXML or QueryExpression?

Can I keep them all?

Realtime vs batch?

Expectation vs reality. Batches aren’t ideal, but in some cases, we may not even have API available to integrate with. It’s not like we choose. For some areas like IoT, banking, blockchain etc you don’t even think “batches”. It depends.

No code/ low code or hardcore development?

Smart code. Saying you are pro-code or pro-nocode means you are too lazy to think of the best in each case solution. You have to learn about all possibilities and consider all options.

Generally for integration which technology and pattern is your choice?

My choice is to provide my customer with the decision-making matrix, so they know their options.

Any open-source, community development, toolbox plugin that you want someone to develop?

I want to develop a per-component backup restore for the portal packages available via Portal Record Mover in XrmToolBox. But I can’t find a time to do it, unfortunately.

If you have all the resources to improve one thing in D365 what that would be?

ALM

What is one thing in model apps you consider people are not utilising its full potential?

Not sure. It depends on the client.

If you are selling D365 just by one feature, what that feature is?

It plays nicely with Office 365.

What would you advise a girl starting in IT and working with Power Platform?

“If you don’t ask questions you look like you know stuff, if you ask questions you actually know it. Don’t look smart, be smart. It’s scary to be the only girl in a room but if it’s what you like to do then be brave and follow your dream. We all hope for a better more diverse, more inclusive world. Be a part of a good change. I love Power Platform because it allows people with no dev background to start building apps and solve business problems. It can be a great way to fall in love with technologies.”

What advice will you give your younger self who is already working as a D365 CE professional?

I’ve done well by choosing it as your career path don’t worry about stopping being a hands-on person; it will never happen.

What are a few things you do to be efficient in working?

If I can’t move faster to achieve my goals, I simply move. People don’t get the concept of time. They worry about something too late to learn or do. If you start today tomorrow, you will be much further than you were yesterday, regardless of speed.

What is the best way to keep up with technological advancements and changes?

Try to keep learning fun, do more hands-on stuff. Don’t believe in everything you see/watch/hear in social media sites. Take small steps but learn regularly.

Thanks Olena.

Let’s Connect 🙂

Let’s Connect

 twIcon lnIcon fbicon

Power Chat with Rasheed Gomaa

0

Mohammed Rasheed Gomaa is a Senior D365 Techno-Functional consultant recently moved to Saudi Arabia from Sydney Australia. Rasheed has authored multiple plugins for XrmToolBox. He is now leading D365 User Group in Riyadh. I have asked him technical questions and also about D365 market in Gulf and how it is to live and work in KSA.

 

Tell us about your professional experience and how you started working with D365 CE / Power Apps? 

I have 11 years of total experience, 9 years as Dynamics CRM CE Techno-Functional consultant, I started working on Dynamics CRM since version 4. I have worked in Australia, USA, Egypt, KSA, and UAE. Currently, I am a Tech Lead in an international company in KSA. I started my D365 career as .Net Developer who did an integration task with CRM, from that time to on, I became a Techno-Functional consultant.

You recently have moved to Saudi Arabia, how is the market there?

KSA is a booming/ greenfield market, not like Australia or USA (with a lot of competition between partners and consultants). Almost all of my projects in KSA are using CE as XRM, not as modules, so we can say XRM is the main module. Then comes Customer Service and Field Service.

For the success of a Power App or D365 CE project, what are a few things (practices or steps) you do when kick-starting a new project?

It’s based on your situation are you working for an end client or partner, but generally:

  • Set the expectations between all project parties:
  • Define the roles and responsibilities.
  • Define artefacts & deliverables.
  • A quick review of the project plan with the team & client.
  • Highlight the risks & the mitigations.
  • Make sure the scope of work is clear to all.
  • Open direct communication channels between key persons in the project.

What delivery methodology you have found useful in projects?

I prefer something between Agile & Waterfall:

For high-level requirement & architecture waterfall, and agile for development & testing.

What is one thing that can make a project successful or vice versa?

There is no magic word in this subject. Still, I believe there are multiple early signs for the failed project, so I think the management should notice this early and apply Plan B.

Give me two (or more) tips that will enhance the performance of an application?

  • Deal with performance as functional requirements.
  • Apply Load Test.
  • Remove unused data/ Plugin/ workflow/ any feature, especially auditing.
  • For on-premise env: Load Balancing.
  • In your code, be careful when you deal with:
  • Lock/ NoLock
  • ConcurrencyBehavior
  • In your plugin always use, “IOrganizationService” instance from plugin context directly.

Tell us two things (or more) which will improve the quality of deliveries?

  1. Pay attention to all “ility” family:
    • Testability.
    • Reusability.
    • Traceability.

2. Automated testing.

3. Apply gamification concept for each dev& test team individually, also avoid long ping-pong game between them.

In the context of D365 implementation, what does architecture means to you?

  1. Prepare a high-level technical solution for business requirements.
  2. Care about both function & non-functional requirements.
  3. Recommend the most suitable business models & technical tool for the project.
  4. Appy design principles.

What few things you consider when you are architecting or designing a solution?

  1. Consider functional & non functional requirements
  2. Set client expectations.
  3. Use the out-of-the-box feature as much as possible.
  4. Avoid any deprecated or not well-supported feature/tool.

Share a tip of yours to boost productivity as a dev, consultant or architect?

  1. Use tools and scripts.
  2. Before developing a feature/ tool, do a search first “don’t reinvent the wheel.”
  3. Follow best practices.

Tell us about a canvas app that you have built or seen which was awesome?

I saw/ did some POC, but still no real implementation.

Have you seen an impressive AI application recently, preconfigured or custom which you want to mention?

Some wonderful POCs on chatbots/ sales/ field service. (none of them was mature enough though).

How do you analyze and build security in projects? Any tips?

  1. Review organization structure (roles, branches/offices). Based on that, you can decide to structure business units. 
  2. Select suitable Hierarchy security to control access (position or managerial).
  3. Ask the client if there are any critical fields to apply field-level security.
  4. As you cannot change the entity ownership from organization to user-team, so do enough analysis to avoid any rework.  

While doing configurations, do you follow some rules or practices?

All configuration should be done automatically by tools, scripts or even by import-export, avoid manual in environments.

Managed or Unmanaged?

It depends, but generally, if you will resell to multiple clients or publish your own IP then it must be managed.

Early bound or late-bound?

I like to autocomplete and reflection, so I use both based on the situation.

LINQ, FetchXML or QueryExpression?

FetchXML is more powerful, especially for manipulating strings 

LINQ is much easier in manipulating the objects  

QueryExpression in the runtime.

Realtime vs batch?

Based on the scenario, but usually, I prefer batch jobs.

No code/ low code or hardcore development?

Depends on the requirements and no/low code tool’s availability and maturity.

In your kingdom, what sort of testing is mandatory (add more value) and which are optional?

Mandatory:

  1. Unit Testing
  2. User Acceptance Test
  3. Functional testing
  4. Integration Testing

Optional (especially for out-of-the-box or low code tools):

  1. Load testing
  2. Automation Testing
  3. Security Testing

Generally for Integration which technology and pattern is your choice?

Depends on client environment and requirement, in general, I prefer APIs & service bus. In some cases, we can use one of the data migrations tools as an integration tool. Custom development still a good approach for some projects.

Any open-source, community development, toolbox plugin that you want someone to develop?

Dynamics 365 community is a vibrant community, we all are searching for an idea to implement.

If you have all the resources to improve one thing in D365 what that would be?

Supporting some languages, especially Arabic, Till now customer insights, Portal and AI still not support Arabic.

If you are selling D365 CE just by one feature, what that feature is?

For me it will be an application customer service or fields service may be.

What will you suggest to someone who wants to be a D365 professional?

Start it now with the online version, initially work for a partner. Be technology hungry and keep attending community events.

What advice will you give your younger self who is already working as a D365 professional?

Before 30 years old do not work on only one project more than 1 year (work for experience), between 30 to 40 work for money and expertise comes itself. After 40″ I cannot tell as I still do not reach that age”.

In addition to:

Be active in the community and think about involving in the community. If you like, do blogging. Share what you know with others. 

Be very careful about your reputation. People first, Project second and company third.

What are a few things you do to be efficient in working?

Teamwork & machine work (automation), by merging both in one environment means you have the black magic.

What is the best way to keep up with technological advancements and changes?

It is tough to be aware of everything, so my recommendation is to keep an eye on Microsoft roadmap and events.

Any recommendation or guideline if a D365 CE professional wants to work in KSA?

 Understanding the mindset/culture of middle eastern people is the keyword to work in KSA. Be patient when dealing with the client as they keep changing the requirements, this still is the most challenge part for me. People are amiable in KSA, so be friendly to them as well. Same time don’t let anyone interfere in your personal life. Set the expectations, borders, requirements and rules from day one. Here the culture of private consultant, contractor, or part-time working is not fully embraced yet. Be cautious when accepting a job, focus on full-time jobs only.

Thank you Rasheed.

D365 & Power Platform New Certifications & Exams

In the year 2019, D365 certifications and exams have undergone many changes. New certifications are replacing the legacy ones. By the mid of 2020, almost all past exams will be retired. I often get a chance to talk to people new to D365 or certifications. Few times I found they are not aware of these changes and focusing on something which is expiring soon. I hope this post will explain these changes and answer a couple of relevant questions.

Should I do certifications?

Years back, when I was planning to shift my career as a Dotnet developer to D365 Consultant, I found a piece of wonderful advice from Mark Smith (MVP). The suggestion was if you do not have a lot of experience of D365 implementations, you should focus on certifications to expand your knowledge and expertise through it. I found this tip profound, and it helped me learn about the product. Certifications are not only helpful when you are new to technology; they help you grow and learn even if you have a lot of experience.

What is the difference in certification and exam?

Certification is the title, document or badge one earns. To do a certification, we may need to pass one or more exams.

What were the previous certifications and exams?

Previously the following certifications were available:

  • Microsoft Certified Solution Associate
  • Microsoft Certified Solution Expert

The following exams are still available for above-mentioned certifications:

  • Microsoft Dynamics 365 Customization and Configuration (MB2-716)
  • Microsoft Dynamics 365 for Retail (MB6-897)
  • Microsoft Dynamics 365 for Talent (MB6-898)

Of course, someone planning to go through these exams should wait (if relevant exams are not released yet) or focus on newly available titles instead of these.

What are the new certifications and exams?

New certifications are offered for the users of three different levels:

  • Fundamentals
  • Associates
  • Expert

One important thing is these new certifications are role-based. These are specific to a functional consultant, developer and solution architect. Fundamentals certifications are right for someone new to these products and technologies, but they are NOT prerequisite for associate certifications. But associate certifications are a must for architect certifications. Another difference is previous certifications were not covering Power Platform very well.

How to prepare for exams?

For preparation training courses are available, and most of the times, they are not free. Their details can be found under relevant exam detail pages. For fans of self-study and learning previously, Microsoft Dynamics Learning Portal was a great resource, but not accessible publically. To make this widely accessible, Microsoft has redeveloped training content which is free and publicly available at https://docs.microsoft.com/en-us/learn/.

I hope these notes were helpful. Enjoy your day.

Let’s Connect

 twIcon lnIcon fbicon