Tuesday, June 13, 2017

Querying Entity collection using LINQ

EntityCollection resulttemp = getContactEntityCollection(erRequest.Id, service);
                                if (resulttemp != null)
                                    List<Entity> listGCRQue = resulttemp.Entities.Where(e => (e.Contains("mms_reason") && ((OptionSetValue)e["OptionsetSchemaname"]).Value == 100000148 || ((OptionSetValue)e["OptionsetSchemaname"]).Value == 100000149 || ((OptionSetValue)e["OptionsetSchemaname"]).Value == 100000150 || ((OptionSetValue)e["OptionsetSchemaname"]).Value == 100000151)).ToList();
                                    List<Entity> listNonGCRQue = resulttemp.Entities.Where(e => (e.Contains("OptionsetSchemaname") && ((OptionSetValue)e["mms_reason"]).Value != 100000148 && ((OptionSetValue)e["OptionsetSchemaname"]).Value != 100000149 && ((OptionSetValue)e["OptionsetSchemaname"]).Value != 100000150 && ((OptionSetValue)e["OptionsetSchemaname"]).Value != 100000151)).ToList();

                                    if ((listGCRQue.Count > 0) || (listGCRQue.Count == 0 && listNonGCRQue.Count != 0 && (reasonValue == 100000148 || reasonValue == 100000149 || reasonValue == 100000150 || reasonValue == 100000151)))
                                        throw new InvalidPluginExecutionException(OperationStatus.Canceled, "Error message");

public EntityCollection getContactEntityCollection(Guid reqId, IOrganizationService service)
            string fetchXml = "";
            fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
                    "<entity name='incident'>" +                  
                    "<attribute name='OptionsetSchemaname' />" +
                    "<attribute name='incidentid' />" +
                    "<filter type='and'>" +
                    "<condition attribute='mms_requestid' operator='eq' value='" + reqId + "' />" +
                    "</filter>" +
                    "</entity>" +

            EntityCollection resulttemp = service.RetrieveMultiple(new FetchExpression(fetchXml));
            if (resulttemp != null && resulttemp.Entities.Count > 0)
                return resulttemp;
                return null;

How to share data b/w plugins

he Microsoft Dynamics CRM 2011 platform and the execution pipeline provides the ability to pass data from one plug-in to another through an IPluginExecutionContext property called SharedVariables. This property is a collection of key/value pairs which developers can use to share data between plug-ins which are registered on both the pre and post events.

 Here is a simple code snippet which shows shared variables in action. We may perform some data validation on the pre-create stage of an Account and then pass an updateRelated boolean variable to a post-create Account plug-in which can perform some additional business logic such as asynchronously updating child records of an Account. Pre-Create Account Plug-in if (context.InputParameters.ContainsKey("Target") && context.InputParameters["Target"] isEntity) { Entity target = context.InputParameters["Target"] as Entity; if (target != null) { // some wacky data validation string city = target.GetAttributeValue("address1_city") ?? string.Empty; int numEmployees = target.GetAttributeValue("numberofemployees"); int accountCategory = target.GetAttributeValue("accountcategorycode"); // city is auckland, numEmployees > 100, account category is preferred customer bool updateRelated = city.Equals("Auckland",StringComparison.InvariantCultureIgnoreCase) && numEmployees > 100 && accountCategory == 1; context.SharedVariables.Add("updatedRelated", updateRelated); } } Post-Create Account Plug-in if (context.InputParameters.ContainsKey("Target") && context.InputParameters["Target"] isEntity) { Entity target = context.InputParameters["Target"] as Entity; if (target != null) { if (context.SharedVariables.ContainsKey("updatedRelated")) { bool updateRelated = (bool)context.SharedVariables["updatedRelated"]; if (updateRelated) { // additional logic to update related records of the Account } } } } That’s all there is to it. This technique lets you build complex plug-ins and pass data between plug-ins without having to set hidden fields on entities.

Tuesday, December 6, 2016

Hide Areas and Sub Areas in the Site Map using Security Roles in Dynamics CRM (Privilege tag)

Hide Areas & Sub Areas in the SiteMap using Security Roles in Dynamics CRM (Privilege tag)

If you need to show or hide a sub area in your SiteMap based on access control security roles, you can easily do this using the Privilege tag in the SiteMap as follows:
<SubArea Id=”crm_myentity” Entity=”crm_myentity”>
<Privilege Entity=”crm_myentity” Privilege=”Read” />
Based on the above, this sub area will only be shown to users who have security roles with read privilege of the custom entity: crm_myentity.
You can add the privilege tag above to any sub area and the entity in the privilege tag can be any entity and doesn’t have to be the same one as the sub area. For example, the following is also applicable:
<SubArea Id=”contact” Entity=”contact” Title=”Contacts”>
<Privilege Entity=”crm_myentity” Privilege=”Read” />
This will hide the contact sub area for users without the read privilege for the entity crm_myentity. You can mix and match as much as you want to show and hide any sub area in the sitemap based on any entity you require whether they are customisable/system or custom entities.
As for hiding and controling access to a whole area in the sitemap such as Sales, Marketing or Service (site map section), you will need to set the privilege tag to every sub area inside this area.
So for example, if you want to hide the whole of the Sales Area for specific users, you need to add the “<privilege  />” tag to every sub area in the Sales Area. What you can also do, is create a custom entity specifically for setting the security on the SiteMap. The following example will hide the Sales (or marketing or service) area for all users who do not have a security role with read access to the custom entity crm_SiteMapPrivilege:
<!–Sales Area–>
<Area Id=”SFA” ResourceId=”Area_Sales” Icon=”/_imgs/sales_24x24.gif” DescriptionResourceId=”Sales_Description”>
<Group Id=”SFA”>
<SubArea Id=”nav_leads” Entity=”lead”>
<Privilege Entity=”crm_myentity” Privilege=”Read” />
<SubArea Id=”nav_oppts” Entity=”opportunity”>
<Privilege Entity=”crm_myentity” Privilege=”Read” />
What you can then do is that, you make every sub area in the Sales area requiring the read privilege of SiteMapPrivilege entity, every sub area under the Marketing area can then have the Write privilege and every sub area under the Service area can have the Create privilege of the crm_SiteMapPrivilege entity. So similar to how the Sales area has read as per the previous example, the Marketing and Service areas can look like this:
<!–Marketing Area–>
<Area Id=”MA” ResourceId=”Area_Marketing” Icon=”/_imgs/marketing_24x24.gif” escriptionResourceId=”Marketing_Description”>
<Group Id=”MA”>
<SubArea Id=”nav_leads” Entity=”lead”>
<Privilege Entity=”crm_myentity” Privilege=”Write” />
<SubArea Id=”nav_accts” Entity=”account”>
<Privilege Entity=”crm_myentity” Privilege=”Write” />
<!–Service Area–>
<Area Id=”CS” ResourceId=”Area_Service” Icon=”/_imgs/services_24x24.gif” DescriptionResourceId=”Customer_Service_Description”>
<Group Id=”CS”>
<SubArea Id=”nav_apptbook”>
<Privilege Entity=”activitypointer” Privilege=”Read” />
<Privilege Entity=”service” Privilege=”Create” />
<SubArea Id=”nav_cases” Entity=”incident>
<Privilege Entity=”service” Privilege=”Create” />

Hence, based on the above 3 examples (Sales, Marketing, Service), you will need to make sure that users who should see the Sales Area has a security role with the read privilege of our custom entity (crm_SiteMapPrivilege), users who should see the Marketing area must have a security role with the Write privilege of crm_SiteMapPrivilege and Create privilege for Service.
The same applies for any additional Areas that you creates. So if you have added a new custom Area in your SiteMap, you should then use another privilege (append, appendto, etc) for every sub area under your new custom Area in the Site Map to show and hide this area based on your chosen privilege.
You can either manually amend your users security roles to add the privilege (read, write, etc..) or alternatively, a much better way of doing this is to create a new security role for each area. So what I have done is I created the following security roles: Access to Sales Area Access to Marketing Area Access to Service Area Access to MyCustom Area
In each security role, I only set the privilege for my custom entity crm_sitemapprivilege as follows:
For Security role: Access to Sales Area, set “Read” on crm_sitemapprivilege For Security role: Access to Marketing Area, set “Write” on crm_sitemapprivilege For Security role: Access to Service Area, set “Create” on crm_sitemapprivilege For Security role: Access to MyCustom Area, set “Append” on crm_sitemapprivilege
Once I’ve done that, I add those security roles to the users based on what they need to see. So for example: User1, need to see sales area, assign security role: Access to Sales Area. User2, need to see marketing area, assign security role: Access to Marketing Area. and so on,
you get the drill.
Last thing to mention is the possible privilege values that you can use. These can be:
All AllowQuickCampaign Append AppendTo Assign Create Delete Read Share Write
you can also use a combination of those values such as: “Read,Write” or “Read,Write,Create” and so on.
so your privilege tag will look something like this:
<Privilege Entity=”crm_sitemapprivilege” Privilege=”Read,Write” />
<!– OR –>
<Privilege Entity=”crm_sitemapprivilege” Privilege=”Read,Write,Share,Write,Append” />
The advantage of using combinations is that it will allow you to do this for as many Areas as you could ever need.

Sitemap Customization Helpful URLs

Sitemap Customization Helpful URLs

1. http://www.mohamedmostafa.co.uk/blog/2012/11/13/hide-areas-sub-areas-in-the-sitemap-using-security-roles-in-dynamics-crm-privilege-tag/

2. https://dipankarbhattacharya.com/2014/05/06/hiding-sitemap-components-based-on-user-profile/

3. https://saikrishnayadav.blogspot.in/2012/10/how-to-hide-marketing-module-for-some.html#comment-form

Wednesday, July 30, 2014

MSCRM Important Technical Links






OData system query options using the OData endpoint



Tuesday, July 29, 2014

Get and Set lookup value using javascript in Dynamics CRM 2013

In this article , I am going to explain how to set and get CRM lookup attribute value using javascript

Get a lookup value
var lookup = new Array();
lookup = Xrm.Page.getAttribute("attributename").getValue();
if (lookup != null) {
    var name = lookup[0].name;
    var id = lookup[0].id;
    var entityType = lookup[0].entityType;

Set a lookup value
var lookup = new Array();
lookup[0] = new Object();
lookup[0].id = recorid;
lookup[0].name = recordname;
lookup[0].entityType = entityname;

Alternate method to set lookup value
Xrm.Page.getAttribute("attributename").setValue([{ id: recorid, name: recordname, entityType: entityname}]);

Wednesday, July 23, 2014

Get Login User Role name in JavaScript using OData

//Check login User has 'System Administrator' role
function CheckUserRole() {
    var currentUserRoles = Xrm.Page.context.getUserRoles();
    for (var i = 0; i < currentUserRoles.length; i++) {
         var userRoleId = currentUserRoles[i];
    var userRoleName = GetRoleName(userRoleId);
        if (userRoleName == "System Administrator") {
            return true;
    return false;
//Get Rolename based on RoleId
function GetRoleName(roleId) {
    //var serverUrl = Xrm.Page.context.getServerUrl();
    var serverUrl = location.protocol + "//" + location.host + "/" + Xrm.Page.context.getOrgUniqueName();
    var odataSelect = serverUrl + "/XRMServices/2011/OrganizationData.svc" + "/" + "RoleSet?$filter=RoleId eq guid'" + roleId + "'";
    var roleName = null;
            type: "GET",
            async: false,
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            url: odataSelect,
            beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
            success: function (data, textStatus, XmlHttpRequest) {
                roleName = data.d.results[0].Name;
            error: function (XmlHttpRequest, textStatus, errorThrown) { alert('OData Select Failed: ' + textStatus + errorThrown + odataSelect); }
    return roleName;