Workflow SerializationException aufgrund eines komplexen Objekts
Frage
Ich bekam die folgende Ausnahme:
System.workflow.runtime.hosting.PersistenceException: Typ 'microsoft.sharepoint.spweb' In Assembly 'Microsoft.SharePoint, Version = 12.0.0.0, Culture = Neutral, PublicKeyToken = 71E9BCE111E9429C' ist nicht als serializierbar bezeichnet. -> System.Runtime.Serialization.SerializationException: Typ 'microsoft.sharepoint.spweb' In Assembly 'Microsoft.SharePoint, Version = 12.0.0.0, Culture = Neutral, PublicKeyToken = 71E9BCE111E9429C' ist nicht als Serializier bezeichnet.
Der Fehler kam von hier aus:
public sealed partial class MyWorkflow : StateMachineWorkflowActivity
{
public SPWorkflowActiviationProperties workflowProperties = new SPWorkflowActivationProperties();
private SPWeb spWebtemp;
private SPWeb spWeb
{
get { return spWebtemp ?? (spWebtemp = workflowProperties.Web); }
}
...
Es gibt zwei Blog -Beiträge, die ich gefunden habe:
- ... ist nicht als serialisierbar gekennzeichnet
- Serialisierungsproblem mit Windows Workflow Foundation und SharePoint Workflow
Es gibt eine Lösung für dieses Problem: Sie haben keine komplexen Mitgliedsobjekte als globale Variablen, Aber als lokale Variablen - dh SPWEB lokal (WorkflowProperties.Web) anstatt auf globaler Ebene deklarieren.
Also müsste ich SPWEB in jeder Methode neu einstellen, die ich verwende - was ich für ziemlich hässlich halte.
Was ich auch versucht habe, ist Folgendes:
...
[NonSerialized]
private SPWeb spWebtemp;
private SPWeb spWeb
{
get { return spWebtemp ?? (spWebtemp = workflowProperties.Web); }
}
...
==> Keine Serialisierungsausnahme mehr!
Gibt es negative Auswirkungen bei der Verwendung der NonSerialized
Attribut auf diesem Feld?
Oder mit anderen Worten - was sind die Auswirkungen?
Lösung
Warum tust du es nicht einfach:
private SPWeb spWeb
{
get { return workflowProperties.Web; }
}
Die faule Last des SPWeb -Objekts wird bereits von der Eigenschafteneigenschaft behandelt
Andere Tipps
Dies sieht so aus, als würde es auch funktionieren (das ondeserialisierte Attribut):
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondserializedAttribute.aspx
BEARBEITEN
Ich habe das nicht getestet, aber ich denke so etwas nach:
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;
}
...
Warum nicht das SpWEBTEMP -Objekt im Konstruktor initialisieren, oder ist das mit Workflows nicht möglich?