Plugin to remove data for a field from Views in Dynamics CRM 2011

Remove specific column data in a view for a security role using Plugin in Microsoft Dynamics CRM 2011
One of the requirements that we come across very frequently in every Dynamics CRM implementation is to restrict few columns for a specific security role. CRM does offer a great flexibility of “Field Level Security” (FLS) to achieve this. But there are some limitations for FLS.
As of now FLS doesn’t support out of the box fields. Which means you cannot apply field level security for the field that will come out of the box. For example, Primary Contact field on Account entity.
Scenario:
Very recently I came across a requirement where my business wants Salesperson to see Account Information but not Contact information.
Approach:
My first step for this is to remove the access to “Contact” for the “Salesperson” security role. This will solve my purpose to restrict the “Salesperson” from seeing the Contacts but he can still see the name id the contact from “Primary Contact” Field of Account form.  
I cannot enable Field Level Security on this field as this is a system filed.
If I delete the existing relationship between Account and Contact and recreate it then it will become a custom field and I can apply Field Level Security. Unfortunately CRM does not allow you to delete system relationships and fields, especially in this case.
So I have created role based forms and do not add the “Primary Contact” field for the form that is accessible for Salesperson. Still there one more component we are missing, Views. We have to remove the information from the views.
So I left with the final option to manipulate the data using Plugin. I can write a plugin on “RetrieveMultiple” message of the account entity and remove the “Primary Contact” field from the Query.
Solutions:
Solution is simple. Write a plugin on “Account” entity for “RetrieveMultiple” in “PreOperation” stage.
*Note: I am using Developer Toolkit for developing my plugin. So your code can differ a little if you writing the plugin as a class library. Give a try with Developer Toolkit for Microsoft Dynamics CRM which can drastically improve your productivity and I am sure you will love it.
var pluginContext = localContext.PluginExecutionContext;

           
IOrganizationService service = localContext.OrganizationService;


QueryExpression query = new QueryExpression()
{
       EntityName = "role",

//Link definition and filter condition
LinkEntities = 
{                            
new LinkEntity
       {
                     LinkFromEntityName = "role",
                     LinkFromAttributeName = "roleid",
              LinkToEntityName = "systemuserroles",
                     LinkToAttributeName = "roleid",
                     LinkCriteria = new FilterExpression
              {
                            FilterOperator = LogicalOperator.And,
              Conditions = 
{
                     new ConditionExpression
                                  {
                                         AttributeName = "systemuserid",
                           Operator = ConditionOperator.Equal,
                                        Values = { pluginContext.UserId }
                                  }     
}
}
}
}
};

query.ColumnSet = new ColumnSet("name");

EntityCollection userroles = service.RetrieveMultiple(query);
bool isSalesPerson = false;

//Check is he is part of salesperson role. Your login can differ based on requirement.
foreach (Entity entity in userroles.Entities)
{
if (entity.Attributes["name"] != null && entity.Attributes["name"].ToString().ToLower() == "salesperson")
       {
              isSalesPerson = true;
              break;
}
}
 
//Manipulate input parameters.         
ParameterCollection collectoin = pluginContext.InputParameters;

if (collectoin["Query"] is QueryExpression && isSalesPerson == true)
{
QueryExpression expression = (QueryExpression)collectoin["Query"];

       ColumnSet columns = expression.ColumnSet;

       //Each column in the view is coming twice. Not sure why.
while (columns.Columns.Contains("primarycontactid"))
       columns.Columns.Remove("primarycontactid");
              
}

Deploy your plugin. Now salesperson will still see the “Primary contact” filed in the view but it will be blank.
If you have any suggestions please leave a comment.

No comments:

Post a Comment