Thursday, November 23, 2023

Understanding Relative Paths in Microsoft Dynamics 365 for Web Resources

 Microsoft Dynamics 365 is a powerful platform that allows businesses to streamline their processes and enhance productivity. One essential aspect of Dynamics 365 customization is the use of web resources, which include scripts, stylesheets, and images that can be embedded directly into forms, dashboards, and other areas of the system. When working with web resources, it's crucial to understand how relative paths function within the Dynamics 365 environment.

What are Relative Paths?

A relative path is a way of specifying the location of a file or resource with respect to the current location. In the context of Microsoft Dynamics 365, relative paths are often used to reference web resources from within the system. Unlike absolute paths that specify the full URL, relative paths provide a more flexible way to reference resources within the same organization.

How Relative Paths Work in Dynamics 365:

  1. Web Resource Structure: In Dynamics 365, web resources are organized into a structure that includes a prefix indicating the type of resource (such as "Web" for web pages or "Script" for scripts) followed by a unique name. When referencing a web resource using a relative path, you start with the prefix and name


// Example of referencing a script web resource
var scriptPath = "/WebResources/new_customscript.js";
Leading Slash (/): The leading slash in a relative path indicates that the path starts from the root of the organization. This is important when referencing resources across different areas of Dynamics 365.


// Reference a web resource at the root level
var imagePath = "/WebResources/new_customimage.png";
Using ".." for Parent Directory: Dynamics 365 supports the use of ".." to reference the parent directory. This can be useful when organizing web resources in subdirectories.


// Reference a script in a subdirectory
var scriptPath = "/WebResources/Scripts/../new_customscript.js";
Dynamic CRM Parameter: When working with web resources, Dynamics 365 provides a global parameter called Xrm.Page.context.getClientUrl(), which returns the base URL of the organization. This parameter can be used to create dynamic relative paths.


// Dynamic reference using Xrm.Page.context.getClientUrl()
var dynamicPath = Xrm.Page.context.getClientUrl() + "/WebResources/new_customscript.js";

Best Practices:

  1. Consistent Folder Structure: Maintain a consistent folder structure for organizing web resources. This makes it easier to manage and reference resources using relative paths.

  2. Considerations for Dynamics 365 Portals: If you're working with Dynamics 365 Portals, be aware that the portal might have its own considerations regarding relative paths, especially if it's exposed externally.

  3. Testing and Debugging: Always test and debug your web resources with relative paths to ensure they are correctly referenced and loaded within the Dynamics 365 environment.

Conclusion:

Understanding how relative paths work in Microsoft Dynamics 365 for web resources is essential for efficient customization and development. By leveraging relative paths, developers can create more flexible and maintainable solutions within the Dynamics 365 ecosystem. As you work with web resources, keep these principles in mind to enhance the effectiveness of your Dynamics 365 implementation.

Wednesday, October 18, 2023

Difference Between String and string in C#

In the world of C# programming, a fundamental concept that often leads to confusion, especially among newcomers, is the distinction between "String" and "string." Both of these terms seem to represent the same thing, but they have subtle differences that can impact the behavior of your code. In this blog post, we will explore the distinctions between "String" and "string" in C# and clarify when and how to use them effectively.

1. Case Sensitivity

The most apparent difference between "String" and "string" in C# is their case sensitivity. "String" with a capital 'S' is a class in the .NET Framework, while "string" with a lowercase 's' is an alias for the "System.String" class. This means that the two can often be used interchangeably, but "string" is typically preferred for simplicity and consistency.



String str1 = "Hello, World!";
string str2 = "Hello, C#!";

While both "str1" and "str2" are essentially the same, it's recommended to use "string" to adhere to C#'s coding conventions and enhance code readability.

2. Performance and Memory

From a performance perspective, there is virtually no difference between "String" and "string." Both represent immutable strings, and C# ensures efficient memory management for them. However, there is one important detail to consider: when you manipulate a string using methods that modify it, a new string object is created, and the original string remains unchanged. This can lead to performance issues when dealing with large strings or frequent modifications.



string original = "Hello";
string modified = original.Replace("H", "M"); // A new string is created.

To address this, you can use the "StringBuilder" class, which allows you to efficiently modify strings without creating numerous intermediate objects.

3. Consistency and Best Practices

When writing C# code, consistency is crucial for maintaining code quality and making it more readable for both yourself and others. By adhering to established conventions and using "string" instead of "String," you ensure your code aligns with widely accepted practices.

Additionally, C# developers often utilize code analysis tools and linters, which might flag the use of "String" instead of "string" as a potential issue or style violation. To avoid these warnings and errors, it's best to stick with "string."

 

Conclusion

 In C#, understanding the difference between "String" and "string" is essential for writing clean, efficient, and maintainable code. While these terms represent the same fundamental concept of strings, it is recommended to use "string" for consistency and readability. Keep in mind that both are used to create immutable strings, and when performing frequent string manipulations, consider using "StringBuilder" to optimize performance. By following these best practices, you'll ensure that your C# code is not only efficient but also easier to work with and maintain.

Sunday, October 15, 2023

Select Assigned Roles to User Using User GUID in JavaScript

 In Microsoft Dynamics 365 (CRM), managing user roles and permissions is a fundamental aspect of security and access control. To retrieve and select the assigned roles for a user using JavaScript, you can use the Web API. Here's how you can do it:


var userId = "user_guid_here";

var query = "/systemusers(" + userId + ")?$expand=systemuserroles_association($select=roleid($select=name))";

Xrm.WebApi.retrieveRecord("systemuser", userId, query).then(
    function success(result) {
        if (result.systemuserroles_association != null) {
            var userRoles = result.systemuserroles_association;
            userRoles.forEach(function (userRole) {
                var roleName = userRole.roleid.name;
                console.log("Assigned Role: " + roleName);
            });
        }
    },
    function error(error) {
        console.log(error.message);
    }
);

This JavaScript code uses the Web API to retrieve the user's assigned roles and log them to the console.

Managing user roles and permissions in Microsoft Dynamics 365 is crucial for ensuring the security and proper access control of your CRM system. By using JavaScript, you can programmatically select the assigned roles for a user based on their user GUID, allowing for more efficient role management and integration within your CRM applications. This can be particularly useful when building custom security features or automating role-related tasks.

Select Assigned Roles to User Using User GUID in C#

 n Microsoft Dynamics 365 (CRM), managing user roles and permissions is a fundamental aspect of security and access control. To retrieve and select the assigned roles for a user using C#, you can follow these steps:

Step 1: Authenticate with the CRM Service

You need to authenticate and establish a connection to the CRM service. You can use the CrmServiceClient to achieve this.



var connectionString = "AuthType=Office365;Url=https://yourorg.crm.dynamics.com;Username=username;Password=password;RequireNewInstance=True";
var service = new CrmServiceClient(connectionString);

Step 2: Query the User's Roles

You can use a QueryExpression to fetch the user's roles based on their GUID.


var userId = new Guid("user_guid_here"); var query = new QueryExpression("systemuser"); query.ColumnSet.AddColumns("systemuserid", "fullname"); var userRolesLink = query.AddLink("systemuserroles", "systemuserid", "systemuserid"); userRolesLink.EntityAlias = "userroles"; userRolesLink.AddLink("role", "roleid", "roleid"); query.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId); EntityCollection result = service.RetrieveMultiple(query); if (result.Entities.Count > 0) { var userRoles = result.Entities[0].GetAttributeValue<EntityCollection>("userroles"); foreach (var userRole in userRoles.Entities) { var roleName = userRole.GetAttributeValue<EntityReference>("role").Name; Console.WriteLine($"Assigned Role: {roleName}"); } }

This code will fetch the user's assigned roles based on their GUID and print them to the console.

Managing user roles and permissions in Microsoft Dynamics 365 is crucial for ensuring the security and proper access control of your CRM system. By using C#, you can programmatically select the assigned roles for a user based on their user GUID, allowing for more efficient role management and integration within your CRM applications. This can be particularly useful when building custom security features or automating role-related tasks.

OData POST To Dynamics 365 Web API in C#

OData POST To Dynamics 365 Web API in C#

When working with Dynamics 365 and its Web API, you may often need to create or update records programmatically. One of the ways to achieve this is by using OData to make HTTP POST requests in C#. In this blog post, we'll explore how to perform a POST request to the Dynamics 365 Web API using C#.

Prerequisites

Before we dive into the code, make sure you have the following prerequisites in place:

  1. Dynamics 365 Account: You need access to a Dynamics 365 environment and the necessary credentials to interact with it.
  2. C# Development Environment: Have a C# development environment, such as Visual Studio, installed on your system.
  3. Microsoft.Xrm.Tooling.CrmConnectControl: You'll need this library, which is commonly used for working with Dynamics 365.

Setting Up the Project

  1. Create a new C# console application project in Visual Studio.

  2. Add the Microsoft.Xrm.Tooling.CrmConnectControl NuGet package to your project. This package provides the necessary libraries for interacting with Dynamics 365.

Writing the Code

Now, let's write the C# code to perform a POST request to create a new record in Dynamics 365. In this example, we'll create a new account. 


using Microsoft.Xrm.Tooling.Connector;
using Microsoft.Xrm.Sdk;
using Microsoft.Crm.Sdk.Messages;
using System;

class Program
{
    static void Main(string[] args)
    {
        // Replace these values with your Dynamics 365 connection details.
        string connectionString = "AuthType=Office365;Url=https://yourorg.crm.dynamics.com;Username=username;Password=password;RequireNewInstance=True";

        CrmServiceClient service = new CrmServiceClient(connectionString);

        if (service.IsReady)
        {
            IOrganizationService orgService = (IOrganizationService)service.OrganizationServiceProxy;

            Entity account = new Entity("account");
            account["name"] = "Sample Account";

            Guid accountId = orgService.Create(account);

            Console.WriteLine($"Account created with ID: {accountId}");
        }
        else
        {
            Console.WriteLine("Failed to connect to Dynamics 365.");
        }
    }
}

Code Explanation

  • We establish a connection to Dynamics 365 using the provided connection string.

  • If the connection is successful, we create a new Entity representing an account and set its attributes.

  • We use the Create method to send a POST request to the Dynamics 365 Web API and create a new account.

  • If the creation is successful, we print the ID of the newly created account.

Conclusion

In this blog post, we've learned how to make a POST request to the Dynamics 365 Web API in C# to create records. You can extend this knowledge to update existing records or work with other entities. This approach is valuable for automating tasks and integrating Dynamics 365 with other systems.

Feel free to adapt this code to your specific needs and take advantage of the flexibility and power of Dynamics 365 Web API for your applications.


Prevent firing plugin execution while Creating/Updating record in Dynamics 365

In Microsoft Dynamics 365, custom business logic plays a pivotal role in automating processes and ensuring data quality. However, there are times when you need to perform data operations without having custom business logic applied. These scenarios usually involve bulk data operations where large numbers of records are being created, updated, or deleted. As a developer of a client application, you have the flexibility to control this custom business logic.

To facilitate this, you can pass special optional parameters with your requests to control two types of custom business logic: Synchronous Logic and Power Automate Flows.

Synchronous Logic

Synchronous Logic is used when you want to enable bulk data operations to be completed as quickly as possible. You may choose to bypass synchronous logic when you're certain that the data you're changing meets the organization's requirements, or you have alternative plans to achieve this logic. By bypassing custom synchronous logic, each operation can complete faster, reducing the total time of the bulk operation.

Power Automate Flows

Power Automate Flows, on the other hand, can lead to a backlog of system jobs when used in large numbers, potentially impacting Dataverse performance. To mitigate this performance issue, you can choose not to trigger the flows while performing bulk operations.

Bypass Synchronous Logic

To bypass custom synchronous logic, you can use the "BypassCustomPluginExecution" optional parameter. This alternative avoids the need to locate and disable custom plugins containing synchronous business logic, which would disable the logic for all users while they're turned off. It also ensures that you disable the correct plugins and remember to re-enable them when you're done. Using this optional parameter, you can disable custom synchronous plugins for specific requests sent by an application configured for this option.

Two requirements must be met:

  1. Send the requests using the "BypassCustomPluginExecution" optional parameter.
  2. The user sending the requests must have the "prvBypassCustomPlugins" privilege. By default, only users with the system administrator security role have this privilege.

Please note that "prvBypassCustomPlugins" cannot be assigned through the UI, but it can be added to a security role using the API.

What Does BypassCustomPluginExecution Do?

When you send requests that bypass custom business logic, all synchronous plug-ins and real-time workflows are disabled. However, core Microsoft Dataverse system plug-ins, solution-specific plug-ins, and core behaviors for specific entities are exempted from this disabling. System plug-ins are critical for ensuring data consistency, and disabling them would result in data inconsistencies that might be challenging to rectify.

Solutions provided by Microsoft that use Dataverse, such as Microsoft Dynamics 365 Customer Service and Dynamics 365 Sales, also include essential business logic that cannot be bypassed with this option.

How to Use the BypassCustomPluginExecution Option

You can utilize the "BypassCustomPluginExecution" option with both the SDK for .NET and the Web API.

SDK for .NET:

  1. Set the value as an optional parameter when making requests. Here's an example of how to do it when creating a new account record:
csharp
static void DemonstrateBypassCustomPluginExecution(IOrganizationService service) { Entity account = new("account"); account["name"] = "Sample Account"; CreateRequest request = new() { Target = account }; request.Parameters.Add("BypassCustomPluginExecution", true); service.Execute(request); }
  1. Use the CrmServiceClient.BypassPluginExecution property:
csharp
var service = new CrmServiceClient(connectionString); service.BypassPluginExecution = true; var account = new Entity("account"); account["name"] = "Sample Account"; service.Create(account);

Once this setting is applied to the service, it remains set for all requests sent using the service until it's explicitly set to false.

In conclusion, controlling custom business logic execution in Dynamics 365 is essential for optimizing performance during bulk data operations. The "BypassCustomPluginExecution" option provides the flexibility to enable or disable custom plugins and flows as needed, allowing you to maintain data integrity while performing large-scale operations efficiently.

QueryExpression vs. FetchXML in MS CRM with C#

Microsoft Dynamics CRM (Customer Relationship Management) is a powerful platform that helps organizations streamline their business processe...