Sunday, September 16, 2012

How to hide some system/cuctom views MS CRM 2011 and 4.0

sometimes we get requirements/demands from users that they do not want to see the extra view list.
so we can manage the view list to hide the unnecessary views.

in 4.0 this can be done by using pluing code...
1. follow the link below...
http://blogs.c5insight.com/Home/tabid/40/entryid/23/MS-CRM-4-0-How-to-Hide-System-Views.aspx

2. i got the below code from internet but lost the link, thanks to the author..

a. plugin code

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.SdkTypeProxy;
 
namespace Excitation.PluginHideSystemViews
{
    public class CheckView : IPlugin
    {
        Dictionary<int, StringCollection> _hideViews;
        public CheckView(string Config)                     // Constructor takes Configuration data from registration
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(Config);
                _hideViews = new Dictionary<int, StringCollection>();
                foreach (XmlElement entityNode in doc.SelectNodes("/entities/entity"))
                {
                    StringCollection sc = new StringCollection();
                    foreach (XmlNode viewNode in entityNode.ChildNodes)
                        sc.Add(viewNode.InnerText);
                    string sOTC = entityNode.GetAttribute("otc");
                    if (!String.IsNullOrEmpty(sOTC))
                    {
                        int otc = 0;
                        int.TryParse(sOTC, out otc);
                        if (otc != 0)
                            _hideViews.Add(otc, sc);
                    }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    System.Diagnostics.EventLog.WriteEntry("MSCRMWebService", "Excitation.PluginHideSystemViews.CheckView Constructor: " + ex.Message);
                    _hideViews = new Dictionary<int, StringCollection>();
                }
                catch { }
            }
 
        }
 
        #region IPlugin Members
 
        public void Execute(IPluginExecutionContext context)
        {
            try
            {
                if (!(context.MessageName == MessageName.RetrieveMultiple && context.PrimaryEntityName == EntityName.savedquery.ToString() && context.InputParameters.Contains(ParameterName.Query) && context.OutputParameters.Contains(ParameterName.BusinessEntityCollection)))
                    return;
                QueryExpression qe = context.InputParameters[ParameterName.Query] as QueryExpression;
                if (qe == null)         // Check it's a QueryExpression
                    return;
                ConditionExpression cond = GetCondition(qe.Criteria, "returnedtypecode");
                if (!(cond != null && cond.Operator == ConditionOperator.Equal && cond.Values.Length == 1 && cond.Values[0] is int))       // Check there is an equiality condition on returnedtypecode for an integer value
                    return;
                int otc = (int)cond.Values[0];
                if (!_hideViews.ContainsKey(otc))       // Check that we want to exclude views for this entity
                    return;
                BusinessEntityCollection becViews = (BusinessEntityCollection)context.OutputParameters[ParameterName.BusinessEntityCollection];
                if (!(becViews != null && becViews.EntityName == EntityName.savedquery.ToString()))  // Check there are some views, and they are the right type
                    return;
                StringCollection scHide = _hideViews[otc];
                for (int i = becViews.BusinessEntities.Count - 1; i >= 0; i--)      // Iterate backwards, as items may be removed
                {
                    DynamicEntity de = (DynamicEntity)becViews.BusinessEntities[i]; // BusinessEntityCollection is of type DynamicEntity
                    if (de.Properties.Contains("name") && scHide.Contains((string)de.Properties["name"]))   // Hide this view - i.e. remove it from the collection of returned views
                        becViews.BusinessEntities.RemoveAt(i);
                }
            }
            catch (Exception ex)
            {
                try
                {
                    System.Diagnostics.EventLog.WriteEntry("MSCRMWebService", "Excitation.PluginHideSystemViews.Execute: " + ex.Message);
                }
                catch { }
            }
        }
        private ConditionExpression GetCondition(FilterExpression Filter, string Attribute)
        {
            ConditionExpression ret = null;
            if (Filter != null && Filter.Conditions != null)
                for(int i=0; i<Filter.Conditions.Count;i++)
                {
                    ConditionExpression cond = (ConditionExpression) Filter.Conditions[i];
                    if (cond.AttributeName == Attribute)
                    {
                        ret = cond;
                        break;
                    }
                }
            return ret;
        }
        #endregion
    }
}
b. the unsecured xml

<?xml version="1.0" encoding="utf-8" ?>
<entities>
            <!-- Sample configuration data. Entities are identified by the otc attribute, and views by name-->
            <entity otc="1">
                        <view>Inactive Accounts</view>
                        <view>Accounts: No Orders in Last 6 Months</view>
            </entity>
            <entity otc="4">
                        <view>Leads Opened Last Week</view>
                        <view>Leads Opened This Week</view>
    <Sec_Role>POM Role</Sec_Role>
            </entity>
</entities>
here make sure the entity oct are the object type code for the entities...
c. registed as below...

 

 in MS CRM 2011, we can manage the views by just "Activate" and "deactivate" option as below...
go to settings->entityname->views, then see the below image to find the activate and deactivate options from Action...
 
the above will help to hide the views from all the users all over the business units who ever have acces to the entity.
if we can manage it by security roles...
let us take example, the view from the account should not be visible to other division, as its a custom view for that division.
so we can manage it by Plugin as we did in MS CRM 4.0.
we need to get the security role from the userID of context.
then we can execute our logic...
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Crm.Sdk.Messages;
 
namespace Excitation.PluginHideSystemViews
{
    public class CheckView : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            try
            {
                // Obtain the execution context from the service provider.
                Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));
                // Obtain the organization service reference.
                    IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
 
                // The InputParameters collection contains all the data passed in the message request.
if(CheckRole(context.UserId, "User Role",  service)){
                if (context.InputParameters.Contains("Query") == true && context.InputParameters["Query"] is QueryExpression)
                {
                    QueryExpression qe = (QueryExpression)context.InputParameters["Query"];
                    if (qe.EntityName == "savedquery")
                    {
                        if (qe.Criteria != null)
                        {
                            if (qe.Criteria.Conditions != null)
                            {
                                /*The query is edited to look at views not starting with "My" at the begining of the View Name*/
                                ConditionExpression queryCondition = new ConditionExpression("name", ConditionOperator.NotLike, "My%");
                                qe.Criteria.Conditions.Add(queryCondition);
                                //context.InputParameters.Properties[ParameterName.Query] = qe;
                                context.InputParameters["Query"] = qe;
                            }
                        }
                    }
 
                }
              }
            }
            catch (Exception e)
            {
            }
        }
 
//check if the user belongs to the specified role....
        private static bool CheckRole(Guid UserGuid, string SecurityRole, IOrganizationService CrmService)
        {
            #region Retrieve records from an intersect table via QueryExpression
 
 
            //Create Query Expression to fetch Role Entity
            QueryExpression Query = new QueryExpression()
            {
                //Setting the link entity condition and filter condition criteria/
                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 = { UserGuid }
                                        }
                                    }
                                }
                            }
                        }
            };
            Query.EntityName = "role";
 
            Query.ColumnSet = new ColumnSet(true);
 
 
            // Obtain results from the query expression.
            EntityCollection UserRoles = CrmService.RetrieveMultiple(Query);
 
 
            // Searching for a specified Security Role into the list
            Entity UserSecurityRole = UserRoles.Entities.ToList<Entity>().Find(delegate(Entity RoleEntity)
            {
                return (string)RoleEntity.Attributes["name"] == SecurityRole;
            });
 
            if (UserSecurityRole == null)
            {
                //return false as the role does not present
                return false;
            }
            else
            {
                return true;
            }
 
 
            #endregion
 
        }
    }
}
 
register it as follows...
 
Regards,
yes.sudhanshu
 

1 comment:

  1. Hello,
    Would it work when you have several languages installed organization?
    As for me it is easier to hide views using Disable View functionality.

    ReplyDelete