Friday, June 10, 2011

CRM 4.0 - Error at the stage of creation of the task from plugin

Today I had task to develop plugin which depends on internal logic had to create the task. I used following code inside plugin:

ICrmService crmservice = context.CreateCrmService(false);
task _task = new task();
_task.subject = "Task Subject";

try
{
crmservice.Create(_task);
}
catch(SoapException e)
{
throw new Exception(e.Detail.InnerText);
}


When I tested plugin it threw non-descriptive "Generic SQL error". I switched on trace and found following description of an error:

Exception when executing non-query: insert into QueueItemBase(QueueId, OrganizationId, State, Status, ObjectId, ModifiedOn, Priority, CreatedBy, ObjectTypeCode, TimeZoneRuleVersionNumber, EnteredOn, Title, ModifiedBy, QueueItemId, DeletionStateCode, CreatedOn, UTCConversionTimeZoneCode) values ('00000000-0000-0000-0000-000000000000', '7b839df8-96ea-4ee0-85bf-967a5f9060ef', 0, 2, 'a6341e54-5693-e011-aa0e-000c29d64722', '06/10/2011 11:39:51', 1, 'e490fea9-a809-4f08-b79e-392b9355b9f1', 4212, 0, '06/10/2011 11:39:51', 'Subject', 'e490fea9-a809-4f08-b79e-392b9355b9f1', 'a7341e54-5693-e011-aa0e-000c29d64722', 0, '06/10/2011 11:39:51', 0) Exception: System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "queue_entries". The conflict occurred in database "orgname_MSCRM", table "dbo.QueueBase", column 'QueueId'.
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at Microsoft.Crm.CrmDbConnection.InternalExecuteNonQuery(IDbCommand command)
at Microsoft.Crm.CrmDbConnection.ExecuteNonQuery(IDbCommand command, Boolean impersonate)
at Microsoft.Crm.BusinessEntities.BusinessProcessObject.ExecuteNonQuery(IDbCommand command, ISqlExecutionContext context)

The issue is when you use code ICrmService crmservice = context.CreateCrmService(false) and you don't fill ownerid field of activity this activity automatically is assigned to 'System' user and 'System' user doesn't has any queues (by default any standard user has 2 personal queues - Assigned and In Progress).

So the way out is to create ICrmService instance using code
ICrmService crmservice = context.CreateCrmService(true);
or fill ownerid field of activities.