-
Marketing List Manager Add-On Updated
I’ve updated my Add To Marketing list add-on with additional functionality and a new Name.
New Name
The new name is Marketing List Manager for Dynamics CRM
New Functionality
Marketing List Manager is an plug-in that allows you to both add and remove members from a marketing list – a feature that is not currently available in Microsoft Dynamics CRM 4.0.
Read more about it here.
Dynamics CRM, Workflow 286 views -
Learning how to query for Marketing List Members
This morning I was adding some functionality to my Dynamics Tutorials site and needed to determine if a user was a member of a specific marketing list.
No problem, I thought. I opened up the most excellent Stunnware Tools to create the query.
The only problem is that the Marketing List Member entity, listmember, does not support the RetreiveMultiple message, which means I can’t use QueryExpression to perform the query.
After digging around a while, I found that I could use QueryExpression but I would have to use the LinkEntity property to properly assemble the query. Here is what I came up with:
bool retVar = false; QueryExpression query = new QueryExpression { EntityName = EntityName.list.ToString()}; LinkEntity linkEntity1 = new LinkEntity { JoinOperator = JoinOperator.Natural, LinkFromEntityName = "list", LinkFromAttributeName = "listid", LinkToEntityName = "listmember", LinkToAttributeName = "listid", LinkCriteria = new FilterExpression() }; linkEntity1.LinkCriteria.FilterOperator = LogicalOperator.And; linkEntity1.LinkCriteria.AddCondition(new ConditionExpression { AttributeName = "listid", Operator = ConditionOperator.Equal, Values = new Object[] { marketingListId } }); linkEntity1.LinkCriteria.AddCondition(new ConditionExpression { AttributeName = "entityid", Operator = ConditionOperator.Equal, Values = new Object[] { userId } }); query.LinkEntities.Add(linkEntity1); RetrieveMultipleRequest request = new RetrieveMultipleRequest { ReturnDynamicEntities = true, Query = query }; RetrieveMultipleResponse response = (RetrieveMultipleResponse)crmService.Execute(request); retVar = (response.BusinessEntityCollection.BusinessEntities.Count > 0);
How It Works
1) We start by querying the Marketing List Entity ( list ).
2) We create a link entity that joins the Marketing List Member Entity to the Marketing List Entity.
3) The search criteria is actually specified on the linked, Marketing List Member Entity. We’re asking for a specific userId and a specific marketingListId.
4) Next we add the linked entity to the query.
5) Finally we prepare and execute the request.
Since I am only interested if the contact exists within the marketing list, I simple set a boolean variable to true or false depending if the number of records returned ( found in the BusinessEntityCollection ) is greater than zero.
References
Customization, Development, Dynamics CRM 292 views -
CRM Add-Ons Updated
Last year I created an add-on for Dynamics CRM 4.0 that I called Data Validation. It had two functions:
- User interface validation
- Email management.
This week I decided to split those functions into two separate products.
I also change the licensing from a per-organization fee to a simple flat-fee.
You may read more about these products by visiting their respective product pages:
Dynamics CRM 221 views -
Issue found while upgrading reports from SQL 2005 to SQL 2008
One of my local customers recently moved from Small Business Server 2003 to Small Business Server 2008. Among other things, this required a move from SQL Server 2005 to SQL Server 2008 as well.
The movement of the databases went pretty much without issue, but we ran into some strange behavior with some of the custom CRM reports they had created. The error looked something like this:
Not very helpful at all.
After reviewing the report in Visual Studio and still not finding any issues, I finally started looking at the system itself. That’s when I found this in the SQL Server’s Event Log:
Report data set execution failure. Error: Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Incorrect syntax near ','.Hmm. It keeps getting better and better. Now what exactly does that mean?
Background
It turns out that when the SQL commands they had written to populate the report were sent to the SQL server, they were combined with other SQL commands.
Unfortunately, SQL didn’t like the way the commands were combined. It wanted you to use a semi-colon ( ; ) to separate the commands so it could determine how the commands should be run.
Which is exactly what the error message states.
The Solution
To fix the issue, all I did was to add a semi-colon ( ; ) to the beginning of the custom SQL statement, which looked something like this:
;WITH FilteredAccount ASAnd that solved the problem and the reports ran successfully.
Dynamics CRM, Reporting 255 views -
Teaching a CRM Bootcamp in August
Hi Folks,
Just wanted to let you know I’ll be teaching part of a CRM bootcamp in Raleigh, North Carolina in August, if you have training budget and interest.
Information on the entire bootcamp may be found here.
I’ll be teaching these classes:
Monday, August 9th:
80003A: Workflow in Microsoft Dynamics™ CRM 4.0
Tuesday, August 10th through Thursday, August 12th:
8969: Extending Microsoft Dynamics CRM 4.0
Dynamics CRM 193 views -
Decrypting CRM JavaScript Runtime Errors
If you have spent any time at all writing JavaScript for CRM you have probably made at least one programming error that has resulted in your page failing to work properly.
CRM will display the following in the bottom-left corner of your page:
Not very helpful, and sometimes not very noticeable either. However, when you close the window CRM will display the following dialog:
Now we’re getting somewhere. This is CRM’s built-in error collection tool that the CRM development team uses to record and track errors within CRM. The data is scrubbed of anything that resembles personal or proprietary information then sends the data ( as long as you click Send Error Report ) to a collection server at one of Microsoft’s Internet sites.
But, this information can also be helpful to you, since you caused the error.
If you click the middle link, View the data that will be sent to Microsoft you will see the actual JavaScript error that cause the error on the page:
Well that is all great, good, and wonderful, but what does it mean? Expected what???
You have two options:
1) You can hunt down an Internet that has a character table that lists characters and their numeric value; or:
2) You can turn to Google. Simply paste the message into the search box of Internet Explorer ( the top box ), press Enter, and the results will be shown in your default language on the Google search page:
Alas, Bing Search does not seem to offer the same capability.
So there you have it. Hopefully this will help the next time you accidentally introduce an error into your code.
As a final note, sometimes the information shown in the error message dialog is of no use to you at all. You will see something like, an error occurred on line 743, character 15. Since CRM wraps your code within their code, this type of information is less than useful to you so you may spend more than a little time tracing down your exact problem.
Special thanks to Daniel Cox who showed me the Google trick.
Customization, Dynamics CRM 692 views -
Exploring the CRM Metabase and Those ‘Of’ Attributes
The CRM Metabase web service allows you to retrieve Entity and Attribute information. If you’ve ever retrieved Entity information you may have noticed some interesting things about the list of attributes returned.
Some of the attributes you will see are not normally displayed in the list of attributes you see when viewing the Entity from within the CRM user interface.
I call these attributes the ‘Of’ attributes because they have properties that end with ‘Of' and are related to, or based on, other attributes.
If we explore the CRM AttributeMetadata class you will see the following three properties:
AggregateOf
Gets the name of the attribute that aggregates the value of this property.AttributeOf
Gets the name of that attribute that this attribute extends.CalculationOf
The SDK description says 'For internal use only, but attributes with this property typically contain currency data.Here are examples of ‘Of’ Attributes:
From the Contact Entity:
Attribute Name Attribute Of parentcustomeridname parentcustomerid donotbulkemailname donotbulkemail From the Account Entity:
Attribute Name Calculation Of Aging60_Base Aging60 Revenue_Base Revenue From the Contact Entity:
Attribute Name Aggregate Of owningteam ownerid accountid parentcustomerid So why is this important to me?
Well, that depends on what you are doing with the Metabase. If you are producing documentation, these attributes may or may not me useful to you.
If you are using the Metabase web services to delete attributes, then these attributes are of no use to you because they can’t be deleted since they are maintained internally by CRM. If you delete the ‘parent’ attribute, the related attribute is also deleted. If you attempt to delete the internally generated attribute, you’ll receive an error.
Checking for ‘Of’ attributes
Here is how you check for ‘Of’ attributes using code:
AttributeMetadata attribute = entityResponse.EntityMetadata.Attributes[0]; if ( (attribute.AttributeOf == null) && (attribute.AggregateOf == null) && (attribute.CalculationOf == null) ) { // do something interesting }
Customization, Development, Dynamics CRM 436 views -
White Paper: Microsoft Dynamics CRM Online: Security Features
Microsoft released a new white paper today.
Overview:
Microsoft takes a holistic approach to providing a highly secure environment for Microsoft Dynamics CRM Online. After an overview of the inherent risks to three key areas of the service, the remaining sections of this paper describe how Trustworthy Computing, Microsoft’s core commitment to build software and services that better help protect customers and the industry, is reflected in the design and operation of Microsoft Dynamics CRM Online.
CRM Online, Dynamics CRM 382 views -
Sharing Records Programmatically
On occasion I’ve had the need to programmatically share a record with a CRM user or team. I noticed this morning that the CRM user interface and the CRM web service call to Grant Access don’t actually have the same number of options.
Here is how you would share a record manually, through the CRM interface:
Here is how you do share a record via code ( from the CRM SDK ):
// Create the SecurityPrincipal Object SecurityPrincipal principal = new SecurityPrincipal(); principal.Type = SecurityPrincipalType.User; // PrincipalId is the Guid of the user to whom access is being granted principal.PrincipalId = new Guid("7B222F98-F48A-4AED-9D09-77A19CB6EE82"); // Create the PrincipalAccess Object PrincipalAccess principalAccess = new PrincipalAccess(); // Set the PrincipalAccess Object's Properties principalAccess.Principal = principal; // Gives the principal access to read principalAccess.AccessMask = AccessRights.ReadAccess; // Create the Target Object for the Request TargetOwnedAccount target = new TargetOwnedAccount(); // EntityId is the Guid of the account access is being granted to target.EntityId = new Guid("6A92D3AE-A9C9-4E44-9FA6-F3D5643753C1"); // Create the Request Object GrantAccessRequest grant = new GrantAccessRequest(); // Set the Request Object's properties grant.PrincipalAccess = principalAccess; grant.Target = target; // Execute the Request GrantAccessResponse granted = (GrantAccessResponse)service.Execute(grant);
AccessMask Property
The AccessMask property defines how the record should be shared. The following values are available:
AppendAccess
Specifies the right to append the specified object to another object.
AppendToAccess
Specifies the right to append another object to the specified object.
AssignAccess
Specifies the right to assign the specified object to another security principal.
CreateAccess
Specifies the right to create an instance of the object type.
DeleteAccess
Specifies the right to delete the specified object.
ReadAccess
Specifies the right to read the specified type of object.
ShareAccess
Specifies the right to share the specified object.
WriteAccess
Specifies the right to update (write to) the specified object.
For additional information, visit the CRM SDK topic: AccessRights Enumeration (CrmService).
The example above gives Read access to a record. To specify more than one access right, you use the C# OR assignment operator so that your code looks something like this:
principalAccess.AccessMask |= AccessRights.ReadAccess; principalAccess.AccessMask |= AccessRights.WriteAccess;
The Append Oddity
I noticed something odd about the Assign right this morning. If you are programmatically sharing the record you must supply both Append and AppendTo rights in order for CRM to fully give Append rights to the record. Here is the code:
principalAccess.AccessMask |= AccessRights.AppendAccess; principalAccess.AccessMask |= AccessRights.AppendToAccess;
If you only supply Append and view the sharing assignments through the CRM user interface, you will not see the Append box checked.
Customization, Dynamics CRM 434 views -
Non-Interactive Users and CRM Online
About a year ago Jon White’s article concerning a CRM Online Non-Interactive user type was posted on the CRM Team blog. I thought I’d add some additional information I found last week.
But first, a bit of background from Jon’s article:
A non-interactive user is a user account in Microsoft Dynamics CRM Online that can access the system but only via the web service layer. Essentially, that user can not use the user interface. Service accounts are used to access CRM Online using the service to service model. A service account is a non-interactive user account with the proxy role assigned to it. Microsoft Dynamics Online allows 5 free non-interactive user accounts. To make the user account a non-interactive account, you need to change the access mode. The access attribute is not visible in the UI by default. The attribute is “access mode”, you can either customize the form to show it, or manipulate it by an SDK call. Setting the access mode to non-interactive simultaneously frees up a license and prevents that identity from logging in interactively.
He goes on to tell you how to add the Access Mode field to the System User Entity form so that this field can be changed by the administrator.
You may also find it useful to put the Access Mode on the Active Users View, so that it displays when you are reviewing your user list:
Interesting Observation
Last week I was discussing non-interactive users with a colleague when I noticed a rather interesting situation: If you are out of user licenses for CRM Online you can’t create a non-interactive user through the CRM user interface. Curious, but understandable.
In a nutshell, the New User wizard will inform you that you are out of licenses and not allow you to continue.
You can circumvent the issue by performing these steps:
- Temporarily disable a user
- Create a new user and change their Access Mode setting to Non-Interactive
- Re-enable the user disabled in step 1.
That should do it.
Programmatic User Creation
Nothing, however, will stop you from creating a user programmatically. You just need to supply the proper values. Here’s some sample code:
systemuser user = new systemuser(); user.accessmode = new Picklist(SystemUserAccessMode.NonInteractive); user.firstname = "system"; user.lastname = "integration"; user.businessunitid = new Lookup("businessunit", new Guid("{C9694BD7-C0C4-DE11-B95D-02BF0A0679DB}")); service.Create(user);
As you can see, you only need four properties:
Access Mode
In this case, we’re going to supply NonInteractive as the value, since that is the purpose of our discussion.
First Name
First name of the user.
Last Name
Last name of the user
Business Unit ID
This is the ID of the business unit the user belongs to.
Calling the CrmService.Create method to actually create the user.
Afterwards, any connection that you need to make to CRM Online can use the new non-interactive user instead of a fully-licensed person.
Administration, CRM Online, Dynamics CRM 487 views




