During the recent SharePoint 2007 and Dynamics CRM 3.0 integration project I have come across the issue using QueryExpression class of Dynamics CRM API.
Consider the following scenario:
1. We need to search for the contact in CRM using API and following criteria: contact first name and last name are equal to the values provided by search functionality or email is equal to the value provided by search functionality - email = email_value OR (first name = first_name_value AND last name = last_name_value)
2. If contact exists then we just use the identifier to do something with that contact if not exists - create the contact
Initially I wrote the following code to retrieve the desired contact:
string sEmail = ...; // initialize email value
string sFirstName = ...; // initialize first name
string sLastName = ...; // initialize last name
try
{
QueryExpression queryContact = new QueryExpression();
queryContact.EntityName = "contact";
queryContact.ColumnSet = new AllColumns();
queryContact.Criteria = new FilterExpression();
queryContact.Criteria.FilterOperator = LogicalOperator.Or;
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "emailaddress1";
condition1.Operator = ConditionOperator.Equal;
condition1.Values = new object[] { sEmail };
queryContact.Criteria.Conditions = new ConditionExpression[] { condition1 };
FilterExpression filter1 = new FilterExpression();
filter1.FilterOperator = LogicalOperator.And;
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = "firstname";
condition2.Operator = ConditionOperator.Equal;
condition2.Values = new object[] { sFirstName };
ConditionExpression condition3 = new ConditionExpression();
condition3.AttributeName = "lastname";
condition3.Operator = ConditionOperator.Equal;
condition3.Values = new object[] { sLastName };
filter1.Conditions = new ConditionExpression[] { condition2, condition3 };
queryContact.Criteria.Filters = new FilterExpression[] { filter1 };
BusinessEntityCollection retrievedContacts = service.RetrieveMultiple(queryContact);
if (retrievedContacts.BusinessEntities.Length > 0)
{
gResult = ((contact)retrievedContacts.BusinessEntities[0]).contactid.Value;
}
}
catch (System.Web.Services.Protocols.SoapException soapex)
{
... // error handling
}
catch (Exception ex)
{
... // error handling
}
In my case first name and last name were provided, but email address was empty string. When I ran the code this code - BusinessEntityCollection retrievedContacts = service.RetrieveMultiple(queryContact); - raised an exception: Server was unable to process request. I looked into that very informative exception details and it said "Invalid argument"... After some trial and error process I realized that it was empty condition value that caused an exception.
I changed my code to look as follows:
string sEmail = ...; // initialize email value
string sFirstName = ...; // initialize first name
string sLastName = ...; // initialize last name
string sEmptyValue = "Empty";
try
{
QueryExpression queryContact = new QueryExpression();
queryContact.EntityName = "contact";
queryContact.ColumnSet = new AllColumns();
queryContact.Criteria = new FilterExpression();
queryContact.Criteria.FilterOperator = LogicalOperator.Or;
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "emailaddress1";
condition1.Operator = ConditionOperator.Equal;
condition1.Values = new object[] { string.IsNullOrEmpty(sEmail) ? sEmptyValue : sEmail };
queryContact.Criteria.Conditions = new ConditionExpression[] { condition1 };
FilterExpression filter1 = new FilterExpression();
filter1.FilterOperator = LogicalOperator.And;
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = "firstname";
condition2.Operator = ConditionOperator.Equal;
condition2.Values = new object[] { string.IsNullOrEmpty(sFirstName) ? sEmptyValue : sFirstName };
ConditionExpression condition3 = new ConditionExpression();
condition3.AttributeName = "lastname";
condition3.Operator = ConditionOperator.Equal;
condition3.Values = new object[] { string.IsNullOrEmpty(sLastName) ? sEmptyValue : sLastName };
filter1.Conditions = new ConditionExpression[] { condition2, condition3 };
queryContact.Criteria.Filters = new FilterExpression[] { filter1 };
BusinessEntityCollection retrievedContacts = service.RetrieveMultiple(queryContact);
if (retrievedContacts.BusinessEntities.Length > 0)
{
gResult = ((contact)retrievedContacts.BusinessEntities[0]).contactid.Value;
}
}
catch (System.Web.Services.Protocols.SoapException soapex)
{
... // error handling
}
catch (Exception ex)
{
... // error handling
}
After the change all works well.
Consider the following scenario:
1. We need to search for the contact in CRM using API and following criteria: contact first name and last name are equal to the values provided by search functionality or email is equal to the value provided by search functionality - email = email_value OR (first name = first_name_value AND last name = last_name_value)
2. If contact exists then we just use the identifier to do something with that contact if not exists - create the contact
Initially I wrote the following code to retrieve the desired contact:
string sEmail = ...; // initialize email value
string sFirstName = ...; // initialize first name
string sLastName = ...; // initialize last name
try
{
QueryExpression queryContact = new QueryExpression();
queryContact.EntityName = "contact";
queryContact.ColumnSet = new AllColumns();
queryContact.Criteria = new FilterExpression();
queryContact.Criteria.FilterOperator = LogicalOperator.Or;
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "emailaddress1";
condition1.Operator = ConditionOperator.Equal;
condition1.Values = new object[] { sEmail };
queryContact.Criteria.Conditions = new ConditionExpression[] { condition1 };
FilterExpression filter1 = new FilterExpression();
filter1.FilterOperator = LogicalOperator.And;
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = "firstname";
condition2.Operator = ConditionOperator.Equal;
condition2.Values = new object[] { sFirstName };
ConditionExpression condition3 = new ConditionExpression();
condition3.AttributeName = "lastname";
condition3.Operator = ConditionOperator.Equal;
condition3.Values = new object[] { sLastName };
filter1.Conditions = new ConditionExpression[] { condition2, condition3 };
queryContact.Criteria.Filters = new FilterExpression[] { filter1 };
BusinessEntityCollection retrievedContacts = service.RetrieveMultiple(queryContact);
if (retrievedContacts.BusinessEntities.Length > 0)
{
gResult = ((contact)retrievedContacts.BusinessEntities[0]).contactid.Value;
}
}
catch (System.Web.Services.Protocols.SoapException soapex)
{
... // error handling
}
catch (Exception ex)
{
... // error handling
}
In my case first name and last name were provided, but email address was empty string. When I ran the code this code - BusinessEntityCollection retrievedContacts = service.RetrieveMultiple(queryContact); - raised an exception: Server was unable to process request. I looked into that very informative exception details and it said "Invalid argument"... After some trial and error process I realized that it was empty condition value that caused an exception.
I changed my code to look as follows:
string sEmail = ...; // initialize email value
string sFirstName = ...; // initialize first name
string sLastName = ...; // initialize last name
string sEmptyValue = "Empty";
try
{
QueryExpression queryContact = new QueryExpression();
queryContact.EntityName = "contact";
queryContact.ColumnSet = new AllColumns();
queryContact.Criteria = new FilterExpression();
queryContact.Criteria.FilterOperator = LogicalOperator.Or;
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "emailaddress1";
condition1.Operator = ConditionOperator.Equal;
condition1.Values = new object[] { string.IsNullOrEmpty(sEmail) ? sEmptyValue : sEmail };
queryContact.Criteria.Conditions = new ConditionExpression[] { condition1 };
FilterExpression filter1 = new FilterExpression();
filter1.FilterOperator = LogicalOperator.And;
ConditionExpression condition2 = new ConditionExpression();
condition2.AttributeName = "firstname";
condition2.Operator = ConditionOperator.Equal;
condition2.Values = new object[] { string.IsNullOrEmpty(sFirstName) ? sEmptyValue : sFirstName };
ConditionExpression condition3 = new ConditionExpression();
condition3.AttributeName = "lastname";
condition3.Operator = ConditionOperator.Equal;
condition3.Values = new object[] { string.IsNullOrEmpty(sLastName) ? sEmptyValue : sLastName };
filter1.Conditions = new ConditionExpression[] { condition2, condition3 };
queryContact.Criteria.Filters = new FilterExpression[] { filter1 };
BusinessEntityCollection retrievedContacts = service.RetrieveMultiple(queryContact);
if (retrievedContacts.BusinessEntities.Length > 0)
{
gResult = ((contact)retrievedContacts.BusinessEntities[0]).contactid.Value;
}
}
catch (System.Web.Services.Protocols.SoapException soapex)
{
... // error handling
}
catch (Exception ex)
{
... // error handling
}
After the change all works well.
Comments
Post a Comment