As a Microsoft Dynamics 365 CRM Developer with over three years of experience, you’re expected to have a strong grasp of core CRM functionalities, customizations, plugins, workflows, Power Platform integrations, and deployment strategies. Below is a curated list of interview questions and answers to help you prepare effectively.
Section 1: JavaScript in D365 CRM
1. How do you retrieve the value of a field using JavaScript?
Answer:
Use the formContext
to access the field value:
var formContext = executionContext.getFormContext();
var name = formContext.getAttribute("name").getValue();
Note: Always retrieve formContext
from the executionContext
to ensure compatibility.
2. How do you set a field value using JavaScript?
Answer:
Set the value using setValue
:
var formContext = executionContext.getFormContext();
formContext.getAttribute("name").setValue("New Value");
Note: Ensure the field exists and is editable to avoid errors.
3. How do you hide or show a field on a form?
Answer:
Control visibility with setVisible
:
var formContext = executionContext.getFormContext();
formContext.getControl("name").setVisible(false); // Hide
formContext.getControl("name").setVisible(true); // Show
Note: Verify the control exists to prevent runtime errors.
4. How do you disable a field using JavaScript?
Answer:
Disable a field using setDisabled
:
var formContext = executionContext.getFormContext();
formContext.getControl("name").setDisabled(true); // Disable
formContext.getControl("name").setDisabled(false); // Enable
5. How do you handle the form load event in D365?
Answer:
Register a function on the form’s OnLoad
event:
function onLoad(executionContext) {
var formContext = executionContext.getFormContext();
// Add logic here, e.g., set field visibility or default values
}
Note: Add the function to the form’s event handler in the form properties and pass the execution context.
6. How can you retrieve the lookup field value?
Answer:
Access lookup field details as an array:
var formContext = executionContext.getFormContext();
var lookup = formContext.getAttribute("parentcustomerid").getValue();
if (lookup && lookup.length > 0) {
var id = lookup[0].id; // GUID
var name = lookup[0].name; // Display name
var entityType = lookup[0].entityType; // Entity logical name
}
Note: Check for null or empty arrays to avoid errors.
7. How do you call a Web API to retrieve a record using JavaScript?
Answer:
Use Xrm.WebApi
for secure API calls:
var formContext = executionContext.getFormContext();
var accountId = formContext.data.entity.getId().replace(/[{}]/g, "");
Xrm.WebApi.retrieveRecord("account", accountId, "?$select=name,accountnumber").then(
function success(result) {
console.log("Account Name: " + result.name);
},
function (error) {
console.error("Error: " + error.message);
}
);
Note: Specify required fields in the $select
query to optimize performance.
8. How do you validate required fields using JavaScript?
Answer:
Check for empty values and display a notification:
var formContext = executionContext.getFormContext();
if (!formContext.getAttribute("name").getValue()) {
formContext.ui.setFormNotification("Name is required.", "ERROR", "nameValidation");
formContext.getAttribute("name").setRequiredLevel("required");
}
Note: Use unique notification IDs and clear notifications with clearFormNotification
when resolved.
9. How do you get the form type in D365?
Answer:
Retrieve the form type to determine the form’s state:
var formContext = executionContext.getFormContext();
var formType = formContext.ui.getFormType(); // 1 = Create, 2 = Update, 3 = Read Only, 4 = Disabled
Note: Use form type to apply conditional logic (e.g., disable fields on read-only forms).
10. How do you dynamically add an option to an option set field?
Answer:
Add a new option to an option set control:
var formContext = executionContext.getFormContext();
formContext.getControl("statuscode").addOption({
text: "New Option",
value: 100000001 // Use a unique integer not already in use
});
Note: Ensure the value is unique and within the allowed range for the option set.
Section 2: Plugins in D365 CRM
1. What is a plugin in D365, and where does it execute?
Answer:
A plugin is a custom C# class that extends D365’s core functionality by executing server-side logic in response to events like Create, Update, or Delete. Plugins run on the Dynamics 365 server, either online (in a sandbox) or on-premises (full trust).
2. What are the plugin pipeline stages?
Answer:
The plugin execution pipeline has three stages:
- Pre-Validation: Before security checks, outside the transaction.
- Pre-Operation: After validation, before the database operation, within the transaction.
- Post-Operation: After the database operation, within the transaction.
Note: Choose the stage based on whether you need to modify data before or after the core operation.
3. How do you retrieve the target entity in a plugin?
Answer:
Access the target entity from the plugin context:
public void Execute(IServiceProvider serviceProvider)
{
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity target = (Entity)context.InputParameters["Target"];
// Access attributes, e.g., string name = target.GetAttributeValue<string>("name");
}
}
Note: Verify the target exists to avoid null reference errors.
4. What are PreEntityImages and PostEntityImages used for?
Answer:
- PreEntityImages: Contain attribute values before the operation (e.g., for Update/Delete).
- PostEntityImages: Contain attribute values after the operation.
Used to compare old and new values or retrieve unchanged attributes.
Example:
Entity preImage = context.PreEntityImages["PreImage"];
string oldName = preImage.GetAttributeValue<string>("name");
Note: Images must be registered in the plugin step.
5. How do you create a plugin step for an update on an account?
Answer:
In the Plugin Registration Tool:
- Register the plugin assembly.
- Create a step with:
- Message: Update
- Primary Entity: account
- Stage: Pre-Operation or Post-Operation
- Execution Mode: Synchronous or Asynchronous
- Optionally, add filtering attributes to trigger only on specific field changes.
Note: Test the step in a non-production environment first.
6. What is the difference between synchronous and asynchronous plugins?
Answer:
- Synchronous: Executes immediately, blocking the user until completion. Used for critical validations.
- Asynchronous: Runs in the background, not blocking the user. Used for non-critical, time-consuming tasks.
Note: Asynchronous plugins improve user experience but may delay data updates.
7. How do you throw a business error in a plugin?
Answer:
Throw an InvalidPluginExecutionException
to display an error to the user:
throw new InvalidPluginExecutionException("Validation failed: Name cannot be empty.");
Note: Provide clear, user-friendly error messages.
8. How do you perform CRUD operations in a plugin?
Answer:
Use the IOrganizationService
to perform Create, Update, Retrieve, or Delete operations:
var service = (IOrganizationService)serviceProvider.GetService(typeof(IOrganizationService));
Entity account = new Entity("account") { ["name"] = "New Account" };
Guid accountId = service.Create(account);
// Update
account["name"] = "Updated Account";
service.Update(account);
Note: Ensure proper error handling using try-catch blocks.
9. How do you debug a plugin in an online environment?
Answer:
- Install the Plugin Profiler in the Plugin Registration Tool.
- Reproduce the scenario to capture a log.
- Download the log file and attach it in Visual Studio.
- Set breakpoints and replay the plugin execution.
Note: Enable tracing in D365 to capture additional details if needed.
10. What is the difference between Shared and Isolated mode in plugin registration?
Answer:
- Isolated (Sandbox): Runs in a restricted environment with limited access (mandatory for D365 Online).
- Shared (None): Full trust mode with unrestricted access (only for on-premises).
Note: Sandbox mode limits external connections and file system access.
Section 3: Azure Integration with D365
1. What Azure services have you integrated with D365 CRM?
Answer:
Common services include:
- Azure Functions: For serverless logic execution.
- Azure Logic Apps: For workflow automation.
- Azure Service Bus: For asynchronous messaging.
- Azure Blob Storage: For file storage.
- Azure Key Vault: For secure secret management.
- Azure API Management: For exposing secure APIs.
2. How does Azure Service Bus integrate with D365 CRM?
Answer:
- Register a service endpoint in the Plugin Registration Tool.
- Configure a plugin step to send messages to the Service Bus queue or topic.
- An Azure Function, Logic App, or other consumer processes the messages.
Example: A plugin triggers a message on account creation, and an Azure Function updates an external system.
Note: Use SAS or AAD authentication for secure communication.
3. Describe a scenario where you used Azure Functions in D365.
Answer:
Scenario: When an account is created in D365, a plugin triggers an Azure Function to validate the account’s tax ID via a third-party API. The function returns the result, and a Logic App updates a custom field in D365.
Implementation:
- Plugin sends account data to an Azure Service Bus queue.
- Azure Function processes the queue message and calls the API.
- Logic App updates D365 using the Dataverse connector.
4. What authentication methods are used for secure integration with Azure?
Answer:
- OAuth 2.0: For token-based authentication with Azure AD.
- Azure AD App Registration: Uses Client ID/Secret or certificates.
- Managed Identity: For secure, passwordless access between Azure services.
Note: Store secrets in Azure Key Vault for enhanced security.
5. What are the benefits of using Logic Apps over Power Automate?
Answer:
- Advanced Error Handling: Logic Apps offer detailed retry policies and error workflows.
- Scalability: Better suited for enterprise-scale integrations.
- Developer Tools: Supports code view, ARM templates, and Visual Studio integration.
- Custom Connectors: Easier to create and manage custom APIs.
Note: Power Automate is more user-friendly for non-developers.
6. How do you handle failures in Azure-integrated processes?
Answer:
- Retries: Configure retry policies in Azure Functions or Logic Apps.
- Logging: Use Azure Application Insights for monitoring and diagnostics.
- Alerts: Set up notifications via Logic Apps or Azure Monitor.
- Fallbacks: Implement durable functions for complex workflows with state management.
Note: Test failure scenarios to ensure robustness.
7. How can you upload large files from D365 to Azure Blob Storage?
Answer:
- Create a custom plugin or Power Automate flow to extract the file (e.g., from a note attachment).
- Use an Azure Function or Logic App to upload the file to Blob Storage via the Azure Blob Storage connector or SDK.
- Store the Blob URL in a D365 field for reference.
Example:
// Plugin code to extract file
Entity note = service.Retrieve("annotation", noteId, new ColumnSet("documentbody"));
string fileContent = note.GetAttributeValue<string>("documentbody");
// Send to Azure Function via Service Bus
Note: Handle large files in chunks to avoid memory issues.
8. How does throttling affect Azure-D365 integration, and how do you handle it?
Answer:
Throttling occurs when API limits (e.g., Dataverse or Azure) are exceeded, causing delays or errors.
Handling:
- Retry Policies: Implement exponential backoff in Azure Functions or Logic Apps.
- Batch Operations: Use bulk APIs to reduce the number of calls.
- Monitoring: Track API usage with Application Insights.
- Optimization: Cache results or use delta queries where possible.
Note: Review Microsoft’s throttling limits for Dataverse.
9. How do you secure APIs exposed by Azure Functions?
Answer:
- Azure AD Authentication: Require OAuth tokens for access.
- API Keys: Use function-level or host-level keys.
- IP Restrictions: Configure allowed IP ranges in Azure.
- CORS: Restrict cross-origin requests to trusted domains.
Note: Regularly rotate keys and monitor access logs.
10. Can D365 call Azure Functions directly from JavaScript?
Answer:
Yes, using fetch
or XMLHttpRequest
, with proper authentication and CORS configuration:
var formContext = executionContext.getFormContext();
var data = { id: formContext.data.entity.getId() };
fetch("https://yourfunction.azurewebsites.net/api/yourFunc?code=yourApiKey", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.error(error));
Note: Use Azure AD tokens instead of API keys for better security in production.
Wrap-Up Tips
- Share Real Examples: Talk about projects you’ve worked on to show your skills.
- Practice Coding: Be ready to write JavaScript code or fix plugin issues during the interview.
- Focus on Cloud: Highlight your Azure skills, as D365 relies heavily on cloud tools.
- Documentation: Refer to Microsoft’s official documentation for Web API, plugins, and Azure integrations during preparation.