Beiträge getagged ‘HowTo’

Howto: Debugging CRM errors

24 August 2009

Today I had a service call with a customer who got an error on creating appointments. The error message was General Failure in Scheduling Engine

A quick search in the internet revealed that this error message is not an unknown one (at least for Dynamics CRM 3)

Because the description of the articles were not suitable for the customers environment and the CRM system is a newer one ( Dynamics CRM 4), we had to dig further.

We enabled the tracing on the crm application server and set the TraceCategories to *:Error which writes only the message with TraceLevel Error to the trace file.

The generated trace file contained following error
...
Crm Exception: Message: SecLib::CrmCheckPrivilege failed. Returned hr = -2147220960 on UserId: bcf9bb2e-6070-de11-a4a6-000c29abeb6c and PrivilegeId: b5f2ee06-d359-4495-bbda-312aae1c6b1e, ErrorCode: -2147220960
...
MessageProcessor fail to process message 'Book' for 'appointment'.
...

A quick search for the name of the denied privilege showed that the security role of the user doesn’t give him the right to share appointments. Apparently, this right is needed for creating an appointment. After adjusting the security role the error was gone and the customer was happy.

Howto: Retrieve members of a marketing list

16 Juli 2009

Retrieving the members of a marketing list is for one reason a little bit trickier than retrieving other entities: there are no messages for operating with the listmember entity.

Once you have loaded the marketing list, for which you want to retrieve the members, you have to find out of what type the members are. The type of the members is stored in the membertype property of the marketing list.

Following method returns the name of the member entity type

internal string GetMemberType(CrmNumber crmNumber)
{
    switch (crmNumber.Value)
    {
        case ListType.Account:
            return EntityName.account.ToString();
        case ListType.Contact:
            return EntityName.contact.ToString();
        case ListType.Lead:
            return EntityName.lead.ToString();
        default:
            break;
    }
}

With this information we can create the query expression which we use to retrieve the list members.

BusinessEntityCollection RetrieveMembers(list marketinglist)
{
 
 string targetEntity = GetMemberType(marketinglist.membertype);
 
 QueryExpression query = new QueryExpression
 {
   EntityName = targetEntity;
   ColumnSet = new AllColumns();
 };
 
 // link from target entity to listmember
 LinkEntity linkToListMemberEntity = new LinkEntity
 {
   LinkFromEntityName = EntityName.account.ToString();
   LinkFromAttributeName = targetEntity + "id";
   LinkToEntityName = EntityName.listmember.ToString();
   LinkToAttributeName = "entityid";
 };
 
 //link from listmember to list
 LinkEntity linkToMarketingList = new LinkEntity
 {
   LinkFromEntityName = EntityName.listmember.ToString();
   LinkFromAttributeName = "listid";
   LinkToEntityName = EntityName.list.ToString();
   LinkToAttributeName = "listid";
 };
 
 // filter result with the id of the marketing list
 ConditionExpression marketingListIdCondition = new ConditionExpression
 {
   AttributeName = "listid";
   Operator = ConditionOperator.Equal;
   Values = new [] { marketinglist.listid.Value };
 };
 
 linkToMarketingList.LinkCriteria = new FilterExpression();
 linkToMarketingList.LinkCriteria.Conditions.Add(marketingListIdCondition);
 
 linkToListMemberEntity.LinkEntities.Add(linkToMarketingList);
 
 query.LinkEntities.Add(linkToListMemberEntity);
 
 BusinessEntityCollection members = service.RetrieveMultiple(query);
 
 return members;
}