问题描述
我们的一个旧项目使用 Windows Workflow Foundation。 XAML 工作流都在名为 Project16.Workflow
的程序集中定义。但是,此程序集的默认命名空间是 Project16.Servcies.Workflow
。
我们看到的异常:
System.Runtime.DurableInstancing.InstancePersistenceCommandException: The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}LoadWorkflow was interrupted by an error. ---> System.Runtime.Serialization.SerializationException: The deserializer cannot load the type to deserialize because type 'System.Activities.Variable`1+VariableLocation[[Project16.Services.Workflow.OutcomeReportPublishOptions,Project16.Services.Workflow,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null]]' Could not be found in assembly 'System.Activities,Version=4.0.0.0,PublicKeyToken=31bf3856ad364e35'. Check that the type being serialized has the same contract as the type being deserialized and the same assembly is used.
at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserializeInSharedTypeMode(XmlReaderDelegator xmlReader,Int32 declaredTypeID,Type declaredType,String name,String ns)
at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserialize(XmlReaderDelegator xmlReader,RuntimeTypeHandle declaredTypeHandle,String ns)
at ReadArrayOfLocationFromXml(XmlReaderDelegator,XmlObjectSerializerReadContext,XmlDictionaryString,CollectionDataContract )
at System.Runtime.Serialization.CollectionDataContract.readxmlValue(XmlReaderDelegator xmlReader,XmlObjectSerializerReadContext context)
at System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract,XmlReaderDelegator reader)
at System.Runtime.Serialization.XmlObjectSerializerReadContextComplex.InternalDeserializeInSharedTypeMode(XmlReaderDelegator xmlReader,String ns)
at ReadLocationEnvironmentFromXml(XmlReaderDelegator,XmlDictionaryString[],XmlDictionaryString[] )
at System.Runtime.Serialization.ClassDataContract.readxmlValue(XmlReaderDelegator xmlReader,String ns)
at ReadActivityInstanceFromXml(XmlReaderDelegator,String ns)
at ReadActivityInstance.ChildListFromXml(XmlReaderDelegator,String ns)
at ReadActivityInstanceMap.InstanceListFromXml(XmlReaderDelegator,String ns)
at ReadArrayOfActivityInstanceMap.InstanceListFromXml(XmlReaderDelegator,String ns)
at ReadInstanceMapFromXml(XmlReaderDelegator,String ns)
at ReadExecutorFromXml(XmlReaderDelegator,String ns)
at ReadkeyvaluePairOfXNameanyTypenNMwwVNaFromXml(XmlReaderDelegator,String ns)
at System.Runtime.Serialization.NetDataContractSerializer.InternalReadobject(XmlReaderDelegator xmlReader,Boolean verifyObjectName)
at System.Runtime.Serialization.XmlObjectSerializer.InternalReadobject(XmlReaderDelegator reader,Boolean verifyObjectName,DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadobjectHandleExceptions(XmlReaderDelegator reader,DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.Readobject(XmlDictionaryReader reader)
at System.Activities.DurableInstancing.DefaultObjectSerializer.Deserializepropertybag(Stream stream)
at System.Activities.DurableInstancing.GZipObjectSerializer.Deserializepropertybag(Stream stream)
at System.Activities.DurableInstancing.DefaultObjectSerializer.Deserializepropertybag(Byte[] serializedValue)
at System.Activities.DurableInstancing.SerializationUtilities.Deserializepropertybag(Byte[] primitiveDataProperties,Byte[] complexDataProperties,InstanceEncodingOption encodingOption)
at System.Activities.DurableInstancing.LoadWorkflowAsyncResult.ProcesssqlResult(sqlDataReader reader)
at System.Activities.DurableInstancing.sqlWorkflowInstanceStoreAsyncResult.sqlCommandAsyncResultCallback(IAsyncResult result)
--- End of inner exception stack trace ---
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.Runtime.DurableInstancing.InstancePersistenceContext.OuterExecute(InstanceHandle initialInstanceHandle,InstancePersistenceCommand command,Transaction transaction,TimeSpan timeout)
at System.Runtime.DurableInstancing.InstanceStore.Execute(InstanceHandle handle,TimeSpan timeout)
at System.Activities.WorkflowApplication.PersistenceManager.Load(TimeSpan timeout)
at System.Activities.WorkflowApplication.LoadValues(PersistenceManager persistenceManager,TimeoutHelper timeoutHelper,Boolean loadAny)
at System.Activities.WorkflowApplication.LoadCore(TimeSpan timeout,Boolean loadAny,PersistenceManager persistenceManager)
at System.Activities.WorkflowApplication.GetInstance(Guid instanceId,InstanceStore instanceStore,TimeSpan timeout)
at System.Activities.WorkflowApplication.GetInstance(Guid instanceId,InstanceStore instanceStore)
at Project16.Services.Workflow.WorkflowService.GetWorkflowInstance(Guid instanceId) in D:\a\1\s\Project16Development\Project16.Workflow\WorkflowService.cs:line 219
at Project16.Services.Workflow.WorkflowService.<UpdateWorkflows>d__18.MoveNext() in D:\a\1\s\Project16Development\Project16.Workflow\WorkflowService.cs:line 170
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Project16.WebApi.Core.Controllers.WorkflowController.<Process>d__2.MoveNext() in D:\a\1\s\Project16Development\Project16.WebApi.Core\Controllers\WorkflowController.cs:line 22
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__1`1.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__17`1.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__17`1.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterattribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Web.Http.Filters.ActionFilterattribute.<CallOnActionExecutedAsync>d__6.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterattribute.<ExecuteActionFilterasyncCore>d__5.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__10.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__17`1.MoveNext()
--- End of stack trace from prevIoUs location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.dispatcher.HttpControllerdispatcher.<SendAsync>d__15.MoveNext()
我认为问题的症结在于:
The deserializer cannot load the type to deserialize because type 'System.Activities.Variable`1+VariableLocation[[Project16.Services.Workflow.OutcomeReportPublishOptions,PublicKeyToken=31bf3856ad364e35'
我认为问题不在于缺少引用正确的 System.Activities
。
现在,我不明白 OutcomeReportPublishOptions
是在 Project16.Workflow
命名空间下的 Project16.Services.Workflow
中定义的一个类,但看起来它似乎试图从名为 Project16.Services.Workflow
的程序集。
在 XAML 中,它是这样引用的:
<Variable x:TypeArguments="local1:OutcomeReportPublishOptions" Name="publishOptions" />
于是我查看了命名空间,原来它是:
xmlns:local1="clr-namespace:Project16.Services.Workflow"
所以我尝试了:
xmlns:local1="clr-namespace:Project16.Services.Workflow;assembly=Project16.Workflow"
但是问题依然存在。
我错过了什么?
解决方法
原来问题是因为我们重命名了程序集!
我们在重构期间从 Project16.Services.Workflow
移到了 Project16.Workflow
,并且不知道 WWF 在实例存储中采用的二进制序列化。
我通过在旧名称下创建一个新程序集并在其中放置一个类型,设法破解了一个修复程序。