Archive
“Add Existing” button is missing from associated view ribbon – Reason & Fix
We get “Add Existing” button when you have relationship between 2 entities and when you select “Associated View” or “Sub grid” of child entity.
Consider this scenario
- I have 2 custom entities in my system
- Policy Holder
- Policy
- I have 1:N relationship between Policy Holder & Policy (i.e., #1 ‘Policy Holder’ can have #N ‘Policies’)
- I have added a sub grid with name “Whole life Policies” of “Policies” entity, on my “Policy holder” form
- When I select sub grid “Whole life Policies” of “Policies” entity, I get both “Add New Policy” & “Add Existing Policy” buttons on my ribbon
P.S. The availability of “Add Existing” button depends on “Requirement Level” property of “Relationship”
- Going back to the scenario, when I open Relationship form of “Policy Holder” & “Policy”, the “Requirement Level” chosen as “No Constraint”
- That’s why I had “Add Existing Policy” button when I chose Policy Sub grid on “Policy Holder” form
“Add Existing” button will go off if I set “Requirement Level” property to “Business Required”
- Now let me change “Requirement Level” to “Business Required” on Relationship form
- Save & Publish
- Now I don’t get “Add Existing Policy” button when I chose Policy Sub grid on “Policy Holder” form
Take aways :-
- So this is one way of hiding “Add Existing” button by making “Requirement Level” to “No Constraint” on Relationship customization.
- You can also hide the “Add Existing” button by using Ribbon Customizations.
🙂
Reading LinkEntity attributes using Query Expression in CRM 2011
Assume you have to retrieve
- All the “Contact” records with fields “Full Name, Address1_City”
- Along with ‘Account Number’ field of ‘Account’ whom the contacts are associated with.
Relationship between Contact & Account
In CRM, there is out of the box 1:N relationship between Account & Contact.
- Contact has ‘ParentCustomerId’ field as foreignkey of ‘Account’ entity
- ‘Account’ entity’s primary field is ‘AccountId’
Preparing Query Expression
- To get the ‘Contact’ attributes along with LinkEntity (i.e.,Account) attributes (i.e., Account Number), we will write a Query Expression with (Entity as ‘Contact’ and LinkEntity as ‘Account’)
- To read LinkEntity attribute’s we have to read the attribute along with ‘EntityAlias’ of LinkEntity (i.e., EntityAlias.AttributeName)
Below is the query expression
var query = new QueryExpression(“contact”);
var columnNames = new[] { “fullname”,”address1_city” };
query.ColumnSet = new ColumnSet(columnNames);
// ‘Account’ as LinkEntity
var colsAccount = new[] { “accountnumber” };
LinkEntity linkEntityAccount = new LinkEntity() {
LinkFromEntityName = “contact”,
LinkFromAttributeName = “parentcustomerid”,
LinkToEntityName = “account”,
LinkToAttributeName = “accountid”,
JoinOperator = JoinOperator.Inner,
Columns = new ColumnSet(colsAccount),
EntityAlias = “aliasAccount”
};
query.LinkEntities.Add(linkEntityAccount);
// Execute Query using RetrieveMultiple
EntityCollection contacts = this.service.RetrieveMultiple(query);
if (contacts != null) {
foreach (var targetEntity in contacts.Entities) {
// Read “Account Number” along with Alias
var accountNumber = getAttributeValue(targetEntity, “aliasAccount.accountnumber“);
var contactFullname = getAttributeValue(targetEntity, “fullname”);
}
}
/// <summary>
/// Generic function to get value from attribute
/// </summary>
private string getAttributeValue(Entity targetEntity, string attributeName) {
if (string.IsNullOrEmpty(attributeName)) {
return string.Empty;
}
if (targetEntity[attributeName] is AliasedValue) {
return (targetEntity[attributeName] as AliasedValue).Value.ToString();
}
else {
return targetEntity[attributeName].ToString();
}
}
return string.Empty;
}
🙂
Passing configuration data using Plug-in registration tool (Secured vs. Unsecured)
- CRM plugin registration tool contain “Unsecure & Secure” configuration sections while registering a “Step”
- We can pass configuration data and can be used in the plug-in logic.
Secured vs. Unsecured
Below are key differentiations between Secured and Unsecured data configuration
- Access
- Data passed through “Unsecure” section is PUBLIC (i.e., It can be read by any user in CRM).
- Only users with “System Administrator” role have access to the data passed through “Secure” configuration section
- Storage
- “Unsecure” config data will be stored along with the Plugin ‘Step’ registration information (i.e., In SdkMessageProcessingStep entity)
- “Secure” config data will be stored in a separate entity named “SdkMessageProcessingStepSecureConfig”
- Only “System Administrator” has Read access on this entity, hence only users with ‘Sys Admin’ role can access this data
- Both “Secured & Unsecured” configuration data stored as “Plain text” in DB
- Outlook Sync
- “Unsecured” configuration data is downloaded to the user’s computer when they go offline making it Unsecure
- “Secured” configuration data is NOT downloaded to User’s Computer when they go Offline
How to read Configuration data in Plug-in
In our plug-in class, we can define a constructor that passes two parameters (i.e., unsecure configuration and secure configuration)
public class AccountCreateHandler: IPlugin{
public AccountCreateHandler(string unsecure, string secure){
// Do something with the parameter strings.
}
public void Execute(IPluginExecutionContext context){
// Do something here.
}
}
Note :- If you want to read “Secure” configuration in the plug-in code, either change the user context in plugin registration as “CRM administrator ” or Impersonate to “CRM Administrator” role user in the code
🙂
Unable to save Appointment – “Invalid e-mail address” Error
I was getting below error screen when I try to save an Appointment activity.
When I verified the Email address of my Appointment attendees (i.e., Users), they all have E-mail address.
Reason:-
- Though the E-mail addresses are valid, If any of the Users E-mail address has invalid character you get the error
- For example, one of my User’s E-mail address was user1ñ@hotmail.co.uk (Here ñ is invalid)
Fix :-
- Remove invalid characters from E-mail field of Users and save
🙂
Categorizing Reports in CRM
We can categorize reports in CRM so that we can create new view based on the category
Below is a useful article on “How to create new report categories” and create report views based on category
🙂
“Sequence contains no elements” LINQ error – FIX
I was getting below error while querying “AccountSet” using LINQ in my plug-in
System.InvalidOperationException: Sequence contains no elements
Reason:-
- Exception raised when there were no records that matches to the criteria specified in my LINQ query
- I had my query statement as below
var account = orgContext.accountSet.Where(acct => (acct.name == “Rajeev”)).First();
- There were no ‘Accounts’ with name=Rajeev and using of First() resulted “Sequence contains no elements” exception
Fix:-
- Replace the method First() with FirstOrDefault().
- The method FirstOrDefault() returns a null value, if there are no records that matches to the filtering criteria
- Now my LINQ expression looks as below
var account = orgContext.accountSet.Where(acct => (acct.name == “Rajeev”)). FirstOrDefault();
🙂
Add or Remove users to Team programmatically in CRM 2011
In CRM,
- Team is a group of users.
- Each team must be associated with only one Business Unit (BU).
- A team can include users from any business unit, not only the BU with which the team is associated.
- Users can be associated with more than one team.
- You can get the members of Team from “TeamMembership” view
TeamMemberShip view
We can Add or Remove users from Team using below requests programmatically
- AddMembersTeamRequest
- RemoveMembersTeamRequest
Below is the code to add User(s) to a Team
AddMembersTeamRequest memberTeamRequest = new AddMembersTeamRequest();
memberTeamRequest.TeamId = teamId; //Guid of Team
// Prepare Member (i.e.,User) array to add to Team
Guid[] arrMembers = new Guid[2];
arrMembers[0] = userId1; // GUID of User 1
arrMembers[1] = userId2; // GUID of User 2
// Set MemberIds property with “arrMembers”
memberTeamRequest.MemberIds = arrMembers;
// Execute the Request
AddMembersTeamResponse response = (AddMembersTeamResponse)service.Execute(memberTeamRequest);
Below is the code to remove User(s) from a Team
RemoveMembersTeamRequest removeMemberTeamRequest = new RemoveMembersTeamRequest();
removeMemberTeamRequest.TeamId = teamId; //Guid of Team
// Prepare Member (i.e.,User) array to remove from Team
Guid[] arrMembers = new Guid[2];
arrMembers[0] = userId1; // GUID of User 1
arrMembers[1] = userId2; // GUID of User 2
// Set MemberIds property with “arrMembers”
removeMemberTeamRequest.MemberIds = arrMembers;
// Execute the Request
RemoveMembersTeamResponse response = (RemoveMembersTeamResponse)service.Execute(removeMemberTeamRequest);
🙂
Entity was not appearing in “Base Record Type” dropdown while creating ‘Duplicate Detection Rule’
- In one of my requirement, I had to create a ‘Duplicate Detection Rule’ on my custom entity ‘Policy’.
- So to create the ‘Duplicate Detection Rule’, I opened a new ‘Duplicate Detection Rule’ form (i.e., Navigated to “Settings –> Data Management –> Duplicate Detection Rules –> New”)
- I then tried to choose “Policy” as “Base Record Type”, but to my surprise I did not find the “Policy” entity in the “Base Record Type” options list
Reason & Fix
- To find the reason, I verified ‘Policy’ entity customizations
- There I observed “Duplicate detection” checkbox was unchecked, under ‘Data Services’ section
- I checked the “Duplicate detection” checkbox and Save & Published to get the ‘Policy’ entity name option in ‘Base Record Type’ dropdown of ‘Duplicate Detection Rule’
🙂