Introduction
Microsoft Dynamics CRM 4.0 is a complete Business Application Platform that is open for customization as well as extension to suit sophisticated as well as trivial business needs. One way to extend the functionality available for this platform is to use the SDK and write code to call the CRM standard Web services to perform queries and update data operations on CRM Entities, etc.
This 3 part series explains one easy way of using Dynamics CRM 4.0 web services to connect, query, create entity records for a given user who happens to have a specific role (Sales Rep. in our case) and then create User Work Days / Hours Calendar for him /her that is relevant to the User Role he /she is given.
Background
In Microsoft Dynamics CRM 4.0 it is not provided out of the box to have a copy / clone then paste User Work Days/hours Calendar from one user or a template to another user. Hence the code in the article series can help a developer / implementor who is faced with this awkward task when users are created En mass and template / standard properties are required to be entered when a User is created or a role is added to an existing user.
Using the Code
The following points state the code strategy step by step which will be stretched to the 3 part series of this article:
- Establish a connection with a CRM Server instance.
- Obtain an instance of the CRM discovery Web Service (authenticate via Active Directory).
- Locate the target organization, then obtain a security token and read the URL for the CRM Web Service.
- Use CRM Web Service to Execute a Query to Obtain roles assigned to a given user.
- Test if that User has a Role of Sales Rep. If
true
... - Use CRM Web Service to create a user related work Days and Hours Calendar that is read from a template standard user Calendar (or could be from an internal Data Structure). (Part II)
* Note:* Later on, a CRM Workflow custom activity shall execute a system job implemented as a generic Windows Command Shall utility to call this console application and pass a user login * parameter for automatic creation of a user working Days/hours Calendar triggered when a User role of Sales Rep. is given for the user. (Part III).
Before starting to code any Dynamics CRM 4.0 web services based application, a web reference intended to use web services must be set in the Project solution explorer under the web references tree branch.
In this example, 2 web references have been set; the first is a reference to the Discovery web services published by the CRM 4.0 platform and named CrmSdk.Discovery
and the second is a web reference to the CRM 4.0 CRM web Service and named CrmSdk
. The URLs that points to both web references are formatted to match an on-premise Active Directory based deployment of the CRM 4.0 Server components.
Both references are then included in the using
assembly declaration at the top of the source code prefixed by the name space given to the Console Application project of this example.
As we start, we first need to pass 2 command line parameters to set the CRM Server user login and a password ..
if (args.Length != 2)
{
Console.WriteLine( ...);
Return 1;
}
Then the following code serves to create / configure an Instance of the Crm Discovery Service Web Service Proxy.
Note: Url
property is provided as a hardcode string for simplicity but should be passed as a parameter or read from an XML Helper file.
CrmDiscoveryService discoveryservice = new CrmDiscoveryService();
discoveryservice.UseDefaultCredentials = true;
discoveryservice.Url = ...;
Finally an Execute
method call id performed on the Discovery service object instance to retrieve the set of organizations as a RetrieveOrganizationsResponse
CRM type which is then parsed and a Url
to the CRM Service is obtained to initialize an object instance of the CRM Web Service.
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
...
RetrieveOrganizationsResponse orgResponse =
(RetrieveOrganizationsResponse)discoveryService.Execute(orgRequest);
CrmService service = new CrmService();
...
Once a connection is established and a proxy to the CRM web service is obtained, the following code is a standard query expression creation then retrieval of the User roles using 3 tables with inner join between Role
and UserRoles
then between UserRoles
and User
table Where UserRoles
is the intersect table. Please refer to the source code attached.
qe = new QueryExpression();
qe.EntityName = "role";
qe.ColumnSet = new AllColumns();
...
LinkEntity le = new LinkEntity();
le.LinkFromEntityName = "role";
le.LinkFromAttributeName = "roleid";
le.LinkToEntityName = "systemuserroles";
le.LinkToAttributeName = "roleid";
LinkEntity le2 = new LinkEntity();
le2.LinkFromEntityName = "systemuserroles";
le2.LinkFromAttributeName = "systemuserid";
le2.LinkToEntityName = "systemuser";
le2.LinkToAttributeName = "systemuserid";
ce = new ConditionExpression();
ce.AttributeName = "systemuserid";
ce.Operator = ConditionOperator.Equal;
ce.Values = new object[] { myUserId };
le2.LinkCriteria = new FilterExpression();
le2.LinkCriteria.Conditions = new ConditionExpression[] { ce };
le.LinkEntities = new LinkEntity[] { le2 };
qe.LinkEntities = new LinkEntity[] { le };
bec = service.RetrieveMultiple(qe);
...
Points of Interest
When catching an exception for the critical code path that retrieves entity records and querying the CRM backend database, it is important to update the web.config of the CRM web application to change the value of the Key DevErrors
to be set to on
not off
. This will instruct CRM runtime to throw more meaningful error messages to the try catch
exception blocks in your code when calling the CRM Web Service.
History
- First version of this article part