2013-11-22 302 views
1

我有2個自定義實體和日曆規則列表,我試圖每個解析到第三個自定義實體的單獨列表,每天1或2。然後我將這些列表聯合在一起,製作出包含正確實體的最終列表。Dynamics CRM 2011 InvalidWorkflowException

我現在正在試圖通過生成所有實體來完成它之前調試工作流,但我必須先修復幾個處理錯誤。

錯誤,我得到:這使得這些錯誤

Unhandled Exception: System.Activities.InvalidWorkflowException: The following errors were encountered while processing the workflow tree: 
'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "DirectCast(CustomActivityStep1: tijdindelingen maken_1_converted, System.String)". 
Syntax error in cast operator; two arguments separated by comma are required. 

'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "DirectCast(CustomActivityStep1_1_converted, Microsoft.Xrm.Sdk.EntityReference)".Invalid L-value expression.:Reference expressions cannot end with Conversion. The provided expression's type must exactly match the type T of VisualBasicReference<T> or LambdaReference<T>. 
'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "CustomActivityStep1: tijdindelingen maken_1_converted". 
End of expression expected. 

'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "CustomActivityStep1: tijdindelingen maken_1". 
End of expression expected. 

'DynamicActivity': The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "CustomActivityStep1: tijdindelingen maken_1". 
End of expression expected. 

    at System.Activities.Hosting.WorkflowInstance.ValidateWorkflow(WorkflowInstanceExtensionManager extensionManager) 
    at System.Activities.WorkflowApplication.EnsureInitialized() 
    at System.Activities.WorkflowApplication.Enqueue(InstanceOperation operation, Boolean push) 
    at System.Activities.WorkflowApplication.WaitForTurn(InstanceOperation operation, TimeSpan timeout) 
    at System.Activities.WorkflowApplication.InternalRun(TimeSpan timeout, Boolean isUserRun) 
    at Microsoft.Crm.Workflow.SynchronousRuntime.ActivityHost.StartWorkflowExecution(Activity workflow, ICommonWorkflowContext context) 
    at Microsoft.Crm.Workflow.SynchronousRuntime.ActivityHost.StartWorkflow(ICommonWorkflowContext context) 

代碼:

// <copyright file="GenerateTijdIndelingen.cs" company=""> 
// Copyright (c) 2013 All Rights Reserved 
// </copyright> 
// <author></author> 
// <date>11/22/2013 12:28:26 PM</date> 
// <summary>Implements the GenerateTijdIndelingen Workflow Activity.</summary> 

using System.Collections.Generic; 
using System.Globalization; 
using System.Linq; 
using Microsoft.Xrm.Sdk.Messages; 
using Microsoft.Xrm.Sdk.Metadata; 

namespace acm.mscrm2011.hrpro.Workflow 
{ 
    using System; 
    using System.Activities; 
    using System.ServiceModel; 
    using Microsoft.Xrm.Sdk; 
    using Microsoft.Xrm.Sdk.Workflow; 

    public sealed class GenerateTijdIndelingen : CodeActivity 
    { 
     [Input("Personeelsfiche")] 
     [ReferenceTarget(slfn_personeelsfiche.EntityLogicalName)] 
     public InArgument<EntityReference> Personeelsfichereference { get; set; } 
     /// <summary> 
     /// Executes the workflow activity. 
     /// </summary> 
     /// <param name="executionContext">The execution context.</param> 
     protected override void Execute(CodeActivityContext executionContext) 
     { 


      // Create the tracing service 
      ITracingService tracingService = executionContext.GetExtension<ITracingService>(); 

      if (tracingService == null) 
      { 
       throw new InvalidPluginExecutionException("Failed to retrieve tracing service."); 
      } 

      tracingService.Trace("Entered GenerateTijdIndelingen.Execute(), Activity Instance Id: {0}, Workflow Instance Id: {1}", 
       executionContext.ActivityInstanceId, 
       executionContext.WorkflowInstanceId); 

      // Create the context 
      IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>(); 

      if (context == null) 
      { 
       throw new InvalidPluginExecutionException("Failed to retrieve workflow context."); 
      } 

      tracingService.Trace("GenerateTijdIndelingen.Execute(), Correlation Id: {0}, Initiating User: {1}", 
       context.CorrelationId, 
       context.InitiatingUserId); 
      IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>(); 
      // This is where the magic happens   
      Type type = Type.GetType("Microsoft.Crm.Workflow.SynchronousRuntime.WorkflowContext, Microsoft.Crm.Workflow, Version=5.0.0.0"); 
      type.GetProperty("ProxyTypesAssembly").SetValue(serviceFactory, typeof(XrmServiceContext).Assembly, null); 
      IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); 
      XrmServiceContext serviceContext = new XrmServiceContext(service); 

      try 
      { 
       //gegevens ophalen 
       Guid personeelslidGuid = Personeelsfichereference.Get<slfn_personeelsfiche>(executionContext).Id; 
       IEnumerable<CalendarRule> applicableCalendarRules = GetCalendarRules(serviceContext).Where(cr => IsInNMonthsOrLess(cr.StartTime.GetValueOrDefault(), 2)); 
       Guid feestDagGuid = GetAfwezigheidsRedenId(serviceContext, "Feestdag"); 
       IEnumerable<acm_weekkalender> weekkalenders = GetWeekKalender(serviceContext, personeelslidGuid); 
       IEnumerable<acm_afwezigheden> applicableAfwezigheden = GetAfwezighedenForPersoneelslid(serviceContext, personeelslidGuid).Where(afw => IsInNMonthsOrLess(afw.acm_eerstedag.GetValueOrDefault(), 2) || IsInNMonthsOrLess(afw.acm_laatstedag.GetValueOrDefault(), 2)); 
       List<acm_tijdindeling> feestdagTijdindelingen = new List<acm_tijdindeling>(); 

       //calendarrules parsen 
       foreach (CalendarRule calendarRule in applicableCalendarRules) 
       { 
        acm_tijdindeling feestdagtijdindeling = new acm_tijdindeling { acm_personeelsfiche = new EntityReference(slfn_personeelsfiche.EntityLogicalName, personeelslidGuid), acm_starttijdstip = calendarRule.StartTime, acm_eindtijdstip = calendarRule.EndTime.GetValueOrDefault(), acm_iswerktijd = false, acm_redenvanafwezigheid = new EntityReference(acm_afwezigheidsreden.EntityLogicalName, feestDagGuid) }; 
        feestdagtijdindeling.acm_name = String.Format(feestdagtijdindeling.acm_personeelsfiche.Name + " - " + feestdagtijdindeling.acm_redenvanafwezigheid.Name + " - " + feestdagtijdindeling.acm_starttijdstip.GetValueOrDefault().ToShortDateString()); 
        feestdagTijdindelingen.Add(feestdagtijdindeling); 
       } 
       //afwezigheden parsen 
       List<acm_tijdindeling> afwezigheidTijdIndelingen = new List<acm_tijdindeling>(); 
       foreach (acm_afwezigheden acmAfwezigheid in applicableAfwezigheden) 
       { 
        acm_tijdindeling afwezigheidtijdindeling = new acm_tijdindeling { acm_personeelsfiche = new EntityReference(slfn_personeelsfiche.EntityLogicalName, acmAfwezigheid.acm_personeelslid.Id), acm_starttijdstip = acmAfwezigheid.acm_eerstedag.GetValueOrDefault(), acm_eindtijdstip = acmAfwezigheid.acm_laatstedag.GetValueOrDefault(), acm_iswerktijd = false, acm_redenvanafwezigheid = new EntityReference(acm_afwezigheidsreden.EntityLogicalName, acmAfwezigheid.acm_afwezigheidsreden.Id) }; 
        afwezigheidtijdindeling.acm_name = String.Format(afwezigheidtijdindeling.acm_personeelsfiche.Name + " - " + afwezigheidtijdindeling.acm_redenvanafwezigheid.Name + " - " + afwezigheidtijdindeling.acm_starttijdstip.GetValueOrDefault().ToShortDateString()); 
        afwezigheidTijdIndelingen.Add(afwezigheidtijdindeling); 
       } 
       //weekkalenders parsen 
       List<acm_tijdindeling> werktijdIndelingen = new List<acm_tijdindeling>(); 
       foreach (acm_weekkalender acmWeekkalender in weekkalenders) 
       { 
        DateTime contractstartDateTime = DateTime.Now; 
        DateTime contractendDateTime = contractstartDateTime.AddMonths(2); 
        List<DayOfWeek> dayOfWeeks = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>().ToList(); 
        CultureInfo dutchCultureInfo = new CultureInfo("nl-BE"); 
        Array vmnmList = Enum.GetValues(typeof(DagDeel)); 
        foreach (DayOfWeek dayOfWeek in dayOfWeeks) 
        { 
         // The (... + 7) % 7 ensures we end up with a value in the range [0, 6] 
         int daysUntilNextDay = ((int)dayOfWeek - (int)contractstartDateTime.DayOfWeek + 7) % 7; 
         DateTime nextDateTime = contractstartDateTime.AddDays(daysUntilNextDay).AddDays((acmWeekkalender.acm_volgnummer.GetValueOrDefault(1) - 1) * 7); 
         string weekdag = dutchCultureInfo.DateTimeFormat.DayNames[(int)dayOfWeek].ToLower(); 
         foreach (DagDeel dagDeel in vmnmList) 
         { 
          string lowerDagDeel = dagDeel.ToString().ToLower(); 
          if (acmWeekkalender.GetAttributeValue<Boolean>("acm_" + weekdag + lowerDagDeel + "vrijaf")) continue; 
          int startuur = acmWeekkalender.GetAttributeValue<OptionSetValue>("acm_" + weekdag + lowerDagDeel + "startuur").Value; 
          int startminuut = acmWeekkalender.GetAttributeValue<OptionSetValue>("acm_" + weekdag + lowerDagDeel + "startminuut").Value; 
          int einduur = acmWeekkalender.GetAttributeValue<OptionSetValue>("acm_" + weekdag + lowerDagDeel + "einduur").Value; 
          int eindminuut = acmWeekkalender.GetAttributeValue<OptionSetValue>("acm_" + weekdag + lowerDagDeel + "eindminuut").Value; 

          DateTime startDateTime = new DateTime(nextDateTime.Year, nextDateTime.Month, nextDateTime.Day, Convert.ToInt16(GetOptionsetText("acm_uren", startuur, service)), Convert.ToInt16(GetOptionsetText("acm_minuten", startminuut, service)), 0, DateTimeKind.Local); 
          DateTime endDateTime = new DateTime(nextDateTime.Year, nextDateTime.Month, nextDateTime.Day, Convert.ToInt16(GetOptionsetText("acm_uren", einduur, service)), Convert.ToInt16(GetOptionsetText("acm_minuten", eindminuut, service)), 0, DateTimeKind.Local); 
          for (DateTime dateTime = nextDateTime; dateTime < contractendDateTime; dateTime.AddDays(7)) 
          { 
           acm_tijdindeling werktijdindeling = new acm_tijdindeling { acm_personeelsfiche = new EntityReference(slfn_personeelsfiche.EntityLogicalName, acmWeekkalender.acm_werknemer.Id), acm_weekkalender = new EntityReference(acm_weekkalender.EntityLogicalName, acmWeekkalender.Id), acm_starttijdstip = startDateTime, acm_eindtijdstip = endDateTime, acm_iswerktijd = true }; 
           werktijdindeling.acm_name = String.Format(werktijdindeling.acm_personeelsfiche.Name + " - " + werktijdindeling.acm_redenvanafwezigheid.Name + " - " + werktijdindeling.acm_starttijdstip.GetValueOrDefault().ToShortDateString()); 
           werktijdIndelingen.Add(werktijdindeling); 
          } 
         } 
        } 
       } 
       //debug info. 
       List<acm_tijdindeling> unionTijdindelingen = feestdagTijdindelingen.Union(afwezigheidTijdIndelingen, new TijdIndelingComparer()).Union(werktijdIndelingen, new TijdIndelingComparer()).ToList(); 
       int aantalFeestdagen = unionTijdindelingen.Count(uti => uti.acm_redenvanafwezigheid.Id.Equals(feestDagGuid)); 
       int aantalwerkdagen = unionTijdindelingen.Count(uti => uti.acm_iswerktijd.GetValueOrDefault()); 
       int aantalAfwezigheidsdagen = unionTijdindelingen.Count(uti => !uti.acm_iswerktijd.GetValueOrDefault(false) && !uti.acm_redenvanafwezigheid.Id.Equals(feestDagGuid)); 
      } 
      catch (FaultException<OrganizationServiceFault> e) 
      { 
       tracingService.Trace("Exception: {0}", e.ToString()); 

       // Handle the exception. 
       throw; 
      } 

      tracingService.Trace("Exiting GenerateTijdIndelingen.Execute(), Correlation Id: {0}", context.CorrelationId); 
     } 
     private static Guid GetAfwezigheidsRedenId(XrmServiceContext serviceContext, string type) 
     { 
      return (from afwr in serviceContext.acm_afwezigheidsredenSet 
        where afwr.acm_name.ToLower(CultureInfo.InvariantCulture).Equals(type.ToLower(CultureInfo.InvariantCulture)) 
        select afwr.Id).First(); 
     } 

     private static IEnumerable<acm_afwezigheden> GetAfwezighedenForPersoneelslid(XrmServiceContext serviceContext, Guid personeelslidGuid) 
     { 
      return (from afw in serviceContext.acm_afwezighedenSet 
        where afw.acm_personeelslid.Id.Equals(personeelslidGuid) 
        select afw); 
     } 

     private static IEnumerable<acm_weekkalender> GetWeekKalender(XrmServiceContext serviceContext, Guid personeelslidGuid) 
     { 
      return (from wk in serviceContext.acm_weekkalenderSet 
        where wk.acm_werknemer.Id.Equals(personeelslidGuid) 
        select wk); 
     } 

     private static bool IsInNMonthsOrLess(DateTime checkedDateTime, int n) 
     { 
      DateTime nowDateTime = DateTime.Now; 
      DateTime nMonthsDateTime = nowDateTime.AddMonths(n); 
      return (nowDateTime <= checkedDateTime && checkedDateTime <= nMonthsDateTime); 
     } 

     private static IEnumerable<CalendarRule> GetCalendarRules(XrmServiceContext serviceContext) 
     { 


      Organization org = (from o in serviceContext.OrganizationSet 
           select o).FirstOrDefault(); 

      if (org != null && org.BusinessClosureCalendarId != null) 
      { 
       Guid businessClosureCalendarId = org.BusinessClosureCalendarId.Value; 
       Calendar businessClosureCalendar = (from c in serviceContext.CalendarSet 
                where c.CalendarId == businessClosureCalendarId 
                select c).FirstOrDefault(); 

       if (businessClosureCalendar != null) 
       { 
        return businessClosureCalendar.CalendarRules; 
       } 
      } return null; 
     } 
     private enum DagDeel 
     { 
      Vm, 
      Nm 
     } 
     private static string GetOptionsetText(string optionsetName, int optionsetValue, IOrganizationService service) 
     { 
      string optionsetSelectedText = string.Empty; 
      RetrieveOptionSetRequest retrieveOptionSetRequest = 
        new RetrieveOptionSetRequest 
        { 
         Name = optionsetName 
        }; 

      // Execute the request. 
      RetrieveOptionSetResponse retrieveOptionSetResponse = 
       (RetrieveOptionSetResponse)service.Execute(retrieveOptionSetRequest); 

      // Access the retrieved OptionSetMetadata. 
      OptionSetMetadata retrievedOptionSetMetadata = (OptionSetMetadata)retrieveOptionSetResponse.OptionSetMetadata; 

      // Get the current options list for the retrieved attribute. 
      OptionMetadata[] optionList = retrievedOptionSetMetadata.Options.ToArray(); 
      foreach (OptionMetadata optionMetadata in optionList) 
      { 
       if (optionMetadata.Value == optionsetValue) 
       { 
        optionsetSelectedText = optionMetadata.Label.UserLocalizedLabel.Label; 
        break; 
       } 
      } 
      return optionsetSelectedText; 
     } 

     private class TijdIndelingComparer : IEqualityComparer<acm_tijdindeling> 
     { 
      public bool Equals(acm_tijdindeling ati1, acm_tijdindeling ati2) 
      { 
       return ati1.acm_starttijdstip.GetValueOrDefault().Date.Equals(ati2.acm_starttijdstip.GetValueOrDefault().Date); 
      } 

      public int GetHashCode(acm_tijdindeling ati) 
      { 
       return ati.acm_starttijdstip.GetHashCode(); 
      } 
     } 
    } 
} 

的3條線在的執行最終都只是爲最終調試,一旦我得到它的工作。

我試圖谷歌爲什麼失敗,但我似乎無法找到任何信息。

編輯:澄清究竟是什麼導致工作流程錯誤。

+0

它看起來不像你列出的錯誤來自你列出的代碼......任何工作流導致插件執行的機會,這是錯誤的地方? – Daryl

+0

我已澄清錯誤來源。 – Nzall

回答

0

我發現這個問題與代碼本身無關。 90%的代碼被註釋掉了,我得到了同樣的錯誤。顯然這是工作流調試器處理早期綁定的問題。一旦我註釋掉了早期綁定,它給出了與插件調試器本身有關的另一個錯誤,它甚至只用3行代碼就解僱了,即服務註冊。

因此,我決定使用不同的調試方法,即通過審慎地使用traceInfos。我還注意到,我應該首先測試我的應用程序本地,因爲在使用DateTimes處理循環時,無限循環的風險很大。

+0

工作流調試程序如何處理早期綁定問題是什麼意思,以及您如何評論它?我有同樣的問題... – Daryl

+0

@Daryl對不起,我不再在我遇到這個問題的公司工作,這是一年多以前,所以我不記得發生了什麼事。我認爲如果你問你的問題,我可能會更好地協助你。 – Nzall