Share via


Sample: Assign a user-owned dashboard to another user

 

Applies To: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

This sample code is for Microsoft Dynamics 365 (online & on-premises). Download the Microsoft Dynamics CRM SDK package. This code can be found in the following location in the download package:

SampleCode\CS\VisualizationsAndDashboards\AssignDashboardToUser.cs

Requirements

For more information about the requirements for running the sample code provided in this SDK, see Use the sample and helper code.

Demonstrates

This sample shows how to assign a user-owned dashboard to another user by using the AssignRequest message. Because you can’t delete a user-owned dashboard that is assigned to another user, this sample shows how to use impersonation to delete the user-owned dashboard.

Example


using System;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;

// These namespaces are found in the Microsoft.Xrm.Sdk.dll assembly
// found in the SDK\bin folder.
using System.Xml.Linq;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Discovery;
using Microsoft.Xrm.Sdk.Client;
// This namespace is found in Microsoft.Crm.Sdk.Proxy.dll assembly
// found in the SDK\bin folder.
using Microsoft.Crm.Sdk.Messages;

using System.DirectoryServices;
using System.Threading;

namespace Microsoft.Crm.Sdk.Samples
{
    public class AssignDashboardToUser
    {
        #region Class Level Members  

        /// <summary>
        /// Stores the organization service proxy.
        /// </summary>
        private OrganizationServiceProxy _serviceProxy;

        // Define the IDs needed for this sample.
        private Guid _userDashboardId;
        private Guid _otherUserId;

        #endregion Class Level Members

        #region How To Sample Code
        /// <summary>
        /// This method first connects to the Organization service. Afterwards,
        /// a user dashbaord is assigned to another user.
        /// </summary>
        /// <param name="serverConfig">Contains server connection information.</param>
        /// <param name="promptforDelete">When True, the user will be prompted to delete all
        /// created entities.</param>
        public void Run(ServerConnection.Configuration serverConfig, bool promptForDelete)
        {
            try
            {

                // Connect to the Organization service. 
                // The using statement assures that the service proxy will be properly disposed.
                using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri,
                                                                     serverConfig.Credentials, serverConfig.DeviceCredentials))
                {
                    // This statement is required to enable early-bound type support.
                    _serviceProxy.EnableProxyTypes();

                    // Call the method to create any data that this sample requires.
                    CreateRequiredRecords();

                    AssignRequest assignRequest = new AssignRequest
                    {
                        Assignee = new EntityReference
                        {
                            LogicalName = SystemUser.EntityLogicalName,
                            // Here we could assign the visualization to the newly created user
                            Id = _otherUserId
                        },

                        Target = new EntityReference
                        {
                            LogicalName = UserForm.EntityLogicalName,
                            Id = _userDashboardId
                        }
                    };
                    _serviceProxy.Execute(assignRequest);

                    Console.WriteLine("The user dashboard has been assigned to Kevin Cook.");


                    DeleteRequiredRecords(promptForDelete);
                }
            }

            // Catch any service fault exceptions that Microsoft Dynamics CRM throws.
            catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)
            {
                // You can handle an exception here or pass it back to the calling method.
                throw;
            }
        }

        /// <summary>
        /// This method creates any entity records that this sample requires.
        /// Creates the dashboard.
        /// </summary>
        public void CreateRequiredRecords()
        {
            //Grab the default public view for opportunities.
            QueryExpression mySavedQuery = new QueryExpression
            {
                ColumnSet = new ColumnSet("savedqueryid"),
                EntityName = SavedQuery.EntityLogicalName,
                Criteria = new FilterExpression
                {
                    Conditions =
                        {
                            new ConditionExpression
                            {
                                AttributeName = "isdefault",
                                Operator = ConditionOperator.Equal,
                                Values = {true}
                            },
                            new ConditionExpression
                            {
                                AttributeName = "querytype",
                                Operator = ConditionOperator.Equal,
                                Values = {0}
                            },
                            new ConditionExpression
                            {
                                AttributeName = "returnedtypecode",
                                Operator = ConditionOperator.Equal,
                                Values = {Opportunity.EntityTypeCode}
                            }
                        }
                }
            };

            //This query should return one and only one result.
            SavedQuery defaultOpportunityQuery = _serviceProxy.RetrieveMultiple(mySavedQuery)
                .Entities.Select(x => (SavedQuery)x).FirstOrDefault();

            // Retrieve visualizations out of the system. 
            // This sample assumes that you have the "Top Opportunities"
            // visualization that is installed with Microsoft Dynamics CRM.
            QueryByAttribute visualizationQuery = new QueryByAttribute
            {
                EntityName = SavedQueryVisualization.EntityLogicalName,
                ColumnSet = new ColumnSet("savedqueryvisualizationid"),
                Attributes = { "name" },
                //If you do not have this visualization, you will need to change
                //this line.
                Values = { "Top Opportunities" }
            };


            SavedQueryVisualization visualization = _serviceProxy.RetrieveMultiple(visualizationQuery).
                Entities.Select(x => (SavedQueryVisualization)x).FirstOrDefault();

            //This is the language code for U.S. English. If you are running this code
            //in a different locale, you will need to modify this value.
            int languageCode = 1033;

            //We set up our dashboard and specify the FormXml. Refer to the
            //FormXml schema in the Microsoft Dynamics CRM SDK for more information.
            UserForm dashboard = new UserForm
            {
                Name = "Sample User Dashboard",
                Description = "Sample user-owned dashboard.",
                FormXml = String.Format(@"<form>
                                <tabs>
                                    <tab name='Test Dashboard' verticallayout='true'>
                                        <labels>
                                            <label description='Sample User Dashboard' languagecode='{0}' />
                                        </labels>
                                        <columns>
                                            <column width='100%'>
                                                <sections>
                                                    <section name='Information Section'
                                                        showlabel='false' showbar='false'
                                                        columns='111'>
                                                        <labels>
                                                            <label description='Information Section'
                                                                languagecode='{0}' />
                                                        </labels>
                                                        <rows>
                                                            <row>
                                                                <cell colspan='1' rowspan='10' 
                                                                    showlabel='false'>
                                                                    <labels>
                                                                        <label description='Top Opportunities - 1'
                                                                        languagecode='{0}' />
                                                                    </labels>
                                                                    <control id='Top10Opportunities'
                                                                        classid='{{E7A81278-8635-4d9e-8D4D-59480B391C5B}}'>
                                                                        <parameters>
                                                                            <ViewId>{1}</ViewId>
                                                                            <IsUserView>false</IsUserView>
                                                                            <RelationshipName />
                                                                            <TargetEntityType>opportunity</TargetEntityType>
                                                                            <AutoExpand>Fixed</AutoExpand>
                                                                            <EnableQuickFind>false</EnableQuickFind>
                                                                            <EnableViewPicker>false</EnableViewPicker>
                                                                            <EnableJumpBar>false</EnableJumpBar>
                                                                            <ChartGridMode>Chart</ChartGridMode>
                                                                            <VisualizationId>{2}</VisualizationId>
                                                                            <EnableChartPicker>false</EnableChartPicker>
                                                                            <RecordsPerPage>10</RecordsPerPage>
                                                                        </parameters>
                                                                    </control>
                                                                </cell>
                                                                <cell colspan='1' rowspan='10' 
                                                                    showlabel='false'>
                                                                    <labels>
                                                                        <label description='Top Opportunities - 2'
                                                                        languagecode='{0}' />
                                                                    </labels>
                                                                    <control id='Top10Opportunities2'
                                                                        classid='{{E7A81278-8635-4d9e-8D4D-59480B391C5B}}'>
                                                                        <parameters>
                                                                            <ViewId>{1}</ViewId>
                                                                            <IsUserView>false</IsUserView>
                                                                            <RelationshipName />
                                                                            <TargetEntityType>opportunity</TargetEntityType>
                                                                            <AutoExpand>Fixed</AutoExpand>
                                                                            <EnableQuickFind>false</EnableQuickFind>
                                                                            <EnableViewPicker>false</EnableViewPicker>
                                                                            <EnableJumpBar>false</EnableJumpBar>
                                                                            <ChartGridMode>Grid</ChartGridMode>
                                                                            <VisualizationId>{2}</VisualizationId>
                                                                            <EnableChartPicker>false</EnableChartPicker>
                                                                            <RecordsPerPage>10</RecordsPerPage>
                                                                        </parameters>
                                                                    </control>
                                                                </cell>
                                                            </row>
                                                            <row />
                                                            <row />
                                                            <row />
                                                            <row />
                                                            <row />
                                                            <row />
                                                            <row />
                                                            <row />
                                                            <row />
                                                        </rows>
                                                    </section>
                                                </sections>
                                            </column>
                                        </columns>
                                    </tab>
                                </tabs>
                            </form>",
                languageCode,
                defaultOpportunityQuery.SavedQueryId.Value.ToString("B"),
                visualization.SavedQueryVisualizationId.Value.ToString("B"))                
            };
            _userDashboardId = _serviceProxy.Create(dashboard);

            Console.WriteLine("Created {0}.", dashboard.Name);

            // Create another user to whom the dashboard will be assigned.
            _otherUserId = SystemUserProvider.RetrieveSalesManager(_serviceProxy);            
        }


        /// <summary>
        /// Deletes the entity record that was created for this sample.
        /// <param name="prompt">Indicates whether to prompt the user 
        /// to delete the entity created in this sample.</param>
        /// The system user named "Kevin Cook" that was created by this sample will
        /// continue to exist on your system because system users cannot be deleted
        /// in Microsoft Dynamics CRM. They can only be enabled or disabled.

        /// </summary>
        public void DeleteRequiredRecords(bool prompt)
        {
            if (!prompt) return;

            // Ask the user if the created entities should be deleted.
            Console.Write("\nDo you want these entity records deleted? (y/n) [y]: ");
            String answer = Console.ReadLine();

            if (answer.StartsWith("y") || answer.StartsWith("Y") || answer == String.Empty)
            {
                // Delete action doesn't work on the UserForm instance if it is assigned
                // to a user other than current user.
                // So as a workaround, we are impersonating the actual owner of 
                // the UserForm instance to complete the delete action.
                // To impersonate another user, set the OrganizationServiceProxy.CallerId
                // property to the ID of the other user.
                _serviceProxy.CallerId = _otherUserId;

                _serviceProxy.Delete(UserForm.EntityLogicalName, _userDashboardId);                
                Console.WriteLine("Entity records have been deleted.");
            }
        }

        #endregion How To Sample Code

        #region Main
        /// <summary>
        /// Main. Runs the sample and provides error output.
        /// <param name="args">Array of arguments to Main method.</param>
        /// </summary>
        static public void Main(string[] args)
        {

            try
            {
                // Obtain the target organization's Web address and client logon 
                // credentials from the user.
                ServerConnection serverConnect = new ServerConnection();
                ServerConnection.Configuration config = serverConnect.GetServerConfiguration();

                AssignDashboardToUser app = new AssignDashboardToUser();
                app.Run(config, true);
            }
            catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
            {
                Console.WriteLine("The application terminated with an error.");
                Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp);
                Console.WriteLine("Code: {0}", ex.Detail.ErrorCode);
                Console.WriteLine("Message: {0}", ex.Detail.Message);
                Console.WriteLine("Plugin Trace: {0}", ex.Detail.TraceText);
                Console.WriteLine("Inner Fault: {0}",
                    null == ex.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
            }
            catch (System.TimeoutException ex)
            {
                Console.WriteLine("The application terminated with an error.");
                Console.WriteLine("Message: {0}", ex.Message);
                Console.WriteLine("Stack Trace: {0}", ex.StackTrace);
                Console.WriteLine("Inner Fault: {0}",
                    null == ex.InnerException.Message ? "No Inner Fault" : ex.InnerException.Message);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine("The application terminated with an error.");
                Console.WriteLine(ex.Message);

                // Display the details of the inner exception.
                if (ex.InnerException != null)
                {
                    Console.WriteLine(ex.InnerException.Message);

                    FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe =
                        ex.InnerException
                        as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;
                    if (fe != null)
                    {
                        Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp);
                        Console.WriteLine("Code: {0}", fe.Detail.ErrorCode);
                        Console.WriteLine("Message: {0}", fe.Detail.Message);
                        Console.WriteLine("Plugin Trace: {0}", fe.Detail.TraceText);
                        Console.WriteLine("Inner Fault: {0}",
                            null == fe.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault");
                    }
                }
            }
            finally
            {
                Console.WriteLine("Press <Enter> to exit.");
                Console.ReadLine();
            }

        }
        #endregion Main

    }
}

See Also

AssignRequest
Actions on dashboards
Assign

Microsoft Dynamics 365

© 2016 Microsoft. All rights reserved. Copyright