{"id":41727,"date":"2025-07-09T14:46:01","date_gmt":"2025-07-09T09:16:01","guid":{"rendered":"https:\/\/www.inogic.com\/blog\/?p=41727"},"modified":"2025-07-09T14:46:01","modified_gmt":"2025-07-09T09:16:01","slug":"proactive-license-validation-in-dynamics-365-streamlining-with-retrieveuserlicenseinforequest","status":"publish","type":"post","link":"https:\/\/www.inogic.com\/blog\/2025\/07\/proactive-license-validation-in-dynamics-365-streamlining-with-retrieveuserlicenseinforequest\/","title":{"rendered":"Proactive License Validation in Dynamics 365: Streamlining with RetrieveUserLicenseInfoRequest"},"content":{"rendered":"<h4><img decoding=\"async\" class=\"alignnone size-full wp-image-41731\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-Streamlining-with-RetrieveUserLicenseInfoRequest.png\" alt=\"Proactive License Validation in Dynamics 365 Streamlining with RetrieveUserLicenseInfoRequest\" width=\"1925\" height=\"1100\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-Streamlining-with-RetrieveUserLicenseInfoRequest.png 1925w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-Streamlining-with-RetrieveUserLicenseInfoRequest-300x171.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-Streamlining-with-RetrieveUserLicenseInfoRequest-1024x585.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-Streamlining-with-RetrieveUserLicenseInfoRequest-768x439.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-Streamlining-with-RetrieveUserLicenseInfoRequest-1536x878.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-Streamlining-with-RetrieveUserLicenseInfoRequest-660x377.png 660w\" sizes=\"(max-width: 1925px) 100vw, 1925px\" \/><\/h4>\n<h4><strong>Introduction<\/strong><\/h4>\n<p>While working on a recent feature for one of our Dynamics 365 solutions, we ran into an issue where users with the right security roles were still facing unexpected &#8220;access denied&#8221; errors. After some investigation, we realized the root cause wasn\u2019t missing permissions\u2014it was missing licenses. This highlighted a common gap in how ISVs and organizations manage access: relying solely on security roles without validating whether users have the required Dynamics 365 or Power Platform licenses.<\/p>\n<p>In Microsoft Dynamics 365 and Power Platform, managing user access effectively is critical for ensuring a seamless user experience and maintaining license compliance. Traditionally, organizations use security roles to manage and restrict access to various features and entities. However, this approach can fall short when a user\u2019s license, rather than their role, determines their ability to perform certain actions.<\/p>\n<p>For example, a user might have the correct security role but still face &#8220;access denied&#8221; errors if they lack the appropriate Dynamics 365 or Power Platform license (e.g., DYN365_SALES_PRO or POWERAPPS_DYN_APPS). This can lead to vague error messages, user frustration, and increased support overhead.<\/p>\n<p>ISVs often create custom roles to manage access to their solutions, but this becomes inefficient when users without valid licenses, such as service accounts or non-CRM users, end up assigned those roles. Until now, there was no straightforward way to programmatically check a user\u2019s license status. That\u2019s when we discovered RetrieveUserLicenseInfoRequest<strong>, <\/strong>a powerful request that allows developers to retrieve detailed license information for any user and use it to enforce license-based logic more reliably.<\/p>\n<p>In this blog, we\u2019ll explore how RetrieveUserLicenseInfoRequest can be used to validate licenses, share practical server-side and client-side implementation examples, and highlight the benefits of proactive license validation for any Dynamics 365 environment.<\/p>\n<h3><strong>Approach: Enhancing Dynamics 365 Solutions with License Validation<\/strong><\/h3>\n<p>Proactive license validation ensures users have the required licenses (e.g., <em>DYN365_SALES_PRO<\/em>, <em>DYN365_ENTERPRISE<\/em>, or <em>POWERAPPS_DYN_APPS<\/em>) before accessing features. This is valuable for organizations and ISVs managing complex user environments or custom applications.<\/p>\n<h4><strong>Understanding RetrieveUserLicenseInfoRequest<\/strong><\/h4>\n<p>The RetrieveUserLicenseInfoRequest class, from <em>Microsoft.Crm.Sdk.Messages<\/em> namespace, retrieves a user\u2019s license information to validate access to features or entities, ensuring compliance and preventing errors. The RetrieveUserLicenseInfoResponse returns detailed license data for verification.<\/p>\n<ul>\n<li><strong>RetrieveUserLicenseInfoRequest Properties:<\/strong><\/li>\n<\/ul>\n<p><em>SystemUserId <\/em>(Guid): The user\u2019s unique ID for the license check.<\/p>\n<ul>\n<li><strong>RetrieveUserLicenseInfoResponse Properties:<\/strong><\/li>\n<\/ul>\n<p><em>licenseInfo <\/em>(LicenseInfo): Contains the user\u2019s license details.<\/p>\n<p><strong>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0a. ServicePlans (Collection of ServicePlan): Lists licenses with:<\/strong><\/p>\n<p>1. Name (String): License internal name (e.g., &#8220;DYN365_SALES_PRO&#8221;).<\/p>\n<p>2. DisplayName (String): User-friendly name (e.g., &#8220;Dynamics 365 Sales Professional&#8221;).<\/p>\n<p>By integrating <strong>RetrieveUserLicenseInfoRequest<\/strong>, you can validate licenses server-side (in plugins) or client-side (in model-driven apps), offering flexibility for various scenarios.<\/p>\n<h4><strong>Server-Side License Validation<\/strong><\/h4>\n<p>For server-side validation, developers can incorporate license checks into plugins to ensure users have the required licenses before performing operations. Below is a code snippet demonstrating how to use RetrieveUserLicenseInfoRequest in a plugin:<\/p>\n<pre class=\"lang:css gutter:true start:1\">try\r\n{\r\ntracingService.Trace(\"Checking license for user ID: {0}\", context.UserId);\r\nvar request = new RetrieveUserLicenseInfoRequest { SystemUserId = context.UserId };\r\nvar licenseResponse= (RetrieveUserLicenseInfoResponse)service.Execute(request);\r\n\/\/ Trace the license information for debugging\r\nif (licenseResponse?.licenseInfo?.ServicePlans != null)\r\n{\r\n_tracingService.Trace($\"Found {licenseResponse.licenseInfo.ServicePlans.Count} service plans for user {userId}:\");\r\nforeach (var plan in licenseResponse.licenseInfo.ServicePlans)\r\n{\r\n_tracingService.Trace($\"Service Plan - Name: {plan.Name}, DisplayName: {plan.DisplayName}\");\r\n}\r\n}\r\nelse\r\n{\r\n_tracingService.Trace(\"licenseResponse or ServicePlans is null.\");\r\n}\r\n_tracingService.Trace(\"RetrieveUserLicenseInfoRequest executed successfully.\");\r\n}\r\ncatch (Exception ex)\r\n{\r\nthrow new InvalidPluginExecutionException($\"License check failed: {ex.Message}\");\r\n}<\/pre>\n<p>Trace Output:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-41728\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365.png\" alt=\"Proactive License Validation in Dynamics 365\" width=\"1744\" height=\"161\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365.png 1744w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-300x28.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-1024x95.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-768x71.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-1536x142.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/07\/Proactive-License-Validation-in-Dynamics-365-660x61.png 660w\" sizes=\"(max-width: 1744px) 100vw, 1744px\" \/><\/p>\n<h4><strong>Client-Side License Validation with Web API<\/strong><\/h4>\n<p>For client-side applications, such as JavaScript-based customizations in model-driven apps, Developers can use the Dynamics 365 Web API to call the RetrieveUserLicenseInfo function.<\/p>\n<p>This enables license validation in scenarios where server-side plugins are not applicable. Below is a code snippet demonstrating how to perform license validation via the Web API.<\/p>\n<pre class=\"lang:css gutter:true start:1\">async function checkUserLicense(systemUserId) {\r\nconst orgUrl = Xrm.Utility.getGlobalContext().getClientUrl() + '\/api\/data\/v9.2\/';\r\nsystemUserId = systemUserId || Xrm.Utility.getGlobalContext().userSettings.userId.replace(\/[{}]\/g, '');\r\nconst requestUrl = new\u00a0\u00a0\u00a0\u00a0\u00a0 URL(`systemusers(${systemUserId})\/Microsoft.Dynamics.CRM.RetrieveUserLicenseInfo`, orgUrl);\r\nconst response = await fetch(requestUrl, {\r\nmethod: 'GET',\r\nheaders: {\r\n'Content-Type': 'application\/json',\r\n'Accept': 'application\/json',\r\n'OData-MaxVersion': '4.0',\r\n'OData-Version': '4.0'\r\n}\r\n});\r\nconst data = await response.json();\r\nconst hasValidLicense = data.licenseInfo?.ServicePlans?.some(sp =&gt; ['DYN365_SALES_PRO', 'DYN365_ENTERPRISE', 'POWERAPPS_DYN_APPS'].includes(sp.Name));\r\nif (!hasValidLicense) {\r\nthrow new Error('You do not have the necessary license to use this feature.');\r\n}\r\nreturn true;\r\n}<\/pre>\n<p><strong>Usage Tip<\/strong>: Call <em>checkUserLicense()<\/em> in the form&#8217;s onload events or ribbon button actions to validate licenses before enabling features.<\/p>\n<h4><strong>Conclusion: Real Productivity Gains<\/strong><\/h4>\n<p>By integrating RetrieveUserLicenseInfoRequest, organizations can build a robust and reliable licensing framework for Dynamics 365 and Power Platform. This approach ensures users have the appropriate licenses (e.g., <em>DYN365_SALES_PRO<\/em>, <em>DYN365_ENTERPRISE<\/em>, or <em>POWERAPPS_DYN_APPS<\/em>) to access features seamlessly, enhancing user satisfaction and operational efficiency.<\/p>\n<p>Key benefits include:<\/p>\n<ul>\n<li><strong>Streamlined Access Control<\/strong>: Validates licenses upfront, ensuring users can perform intended actions without disruptions.<\/li>\n<li><strong>Enhanced Compliance<\/strong>: Ensures adherence to licensing requirements, supporting governance and auditability.<\/li>\n<li><strong>Adaptable Implementation<\/strong>: Offers flexible integration for plugins, scripts, or custom applications.<\/li>\n<\/ul>\n<p>For Dynamics 365 developers, administrators, or ISVs, RetrieveUserLicenseInfoRequest is a vital tool for creating a dependable and user-centric licensing strategy. Try implementing this solution and share your experience in the comments!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction While working on a recent feature for one of our Dynamics 365 solutions, we ran into an issue where users with the right security roles were still facing unexpected &#8220;access denied&#8221; errors. After some investigation, we realized the root cause wasn\u2019t missing permissions\u2014it was missing licenses. This highlighted a common gap in how ISVs\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.inogic.com\/blog\/2025\/07\/proactive-license-validation-in-dynamics-365-streamlining-with-retrieveuserlicenseinforequest\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[18,2361],"tags":[3179],"class_list":["post-41727","post","type-post","status-publish","format-standard","hentry","category-dynamics-365-v9-2","category-technical","tag-proactive-license-validation"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/41727","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/comments?post=41727"}],"version-history":[{"count":0,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/41727\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/media?parent=41727"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/categories?post=41727"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/tags?post=41727"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}