Flusso di lavoro SerializationException A causa dell'oggetto complesso
Domanda
Ho ricevuto la seguente eccezione:
System.workflow.runtime.hosting.PersistenceException: digitare 'Microsoft.Sharepoint.spweb' In Assembly 'Microsoft.SharePoint, versione = 12.0.0.0, Culture = Neutral, PublicKeyToken = 71E9BCE111E9429C' non è contrassegnato come serializzabile. -> System.Runtime.serialization.serializationException: digitare 'Microsoft.Sharepoint.spweb' in Assembly 'Microsoft.SharePoint, versione = 12.0.0.0, Culture = Neutral, PublicKeyToken = 71E9BCE111E9429C' non è contrassegnato come serillizzabile
L'errore è venuto da qui:
public sealed partial class MyWorkflow : StateMachineWorkflowActivity
{
public SPWorkflowActiviationProperties workflowProperties = new SPWorkflowActivationProperties();
private SPWeb spWebtemp;
private SPWeb spWeb
{
get { return spWebtemp ?? (spWebtemp = workflowProperties.Web); }
}
...
Ci sono due post sul blog che ho trovato:
- ... non è contrassegnato come serializzabile
- Problema di serializzazione con Windows Workflow Foundation e SharePoint Workflow
C'è una soluzione da trovare in questo problema: Non hanno oggetti membri complessi come variabili globali, ma come variabili locali - IE dichiarano SPWeb a livello locale (WorkflowProperties.Web) anziché a livello globale.
Quindi dovrei ridecretare SPWeb in ogni metodo che sto usando - che ritengo piuttosto brutto.
Quello che ho anche provato è questo:
...
[NonSerialized]
private SPWeb spWebtemp;
private SPWeb spWeb
{
get { return spWebtemp ?? (spWebtemp = workflowProperties.Web); }
}
...
==> Non più eccezione di serializzazione!
Ci sono implicazioni negative quando si utilizzano il NonSerialized
attributo su questo campo?
O in altre parole - quali sono le implicazioni?
Soluzione
Perché non lo fai semplicemente:
private SPWeb spWeb
{
get { return workflowProperties.Web; }
}
Il carico pigro dell'oggetto SPWeb è già gestito dalla proprietà Properties
Altri suggerimenti
Sembra che funzionerebbe anche (l'attributo ondeserialized):
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedAttribute.aspx
MODIFICARE
Non l'ho provato, ma sto pensando a qualcosa del genere:
public sealed partial class MyWorkflow : StateMachineWorkflowActivity
{
public SPWorkflowActiviationProperties workflowProperties = new SPWorkflowActivationProperties();
[NonSerialized()]
private SPWeb spWebtemp;
private SPWeb spWeb
{
get { return spWebtemp ?? (spWebtemp = workflowProperties.Web); }
}
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
spWebTemp = workflowProperties.Web;
}
...
Inoltre, perché non inizializzare l'oggetto SPWebTemp nel costruttore o non è possibile con i flussi di lavoro?