Flujo de trabajo de serialización de la Excepción por objeto complejo
Pregunta
Tengo la siguiente excepción:
System.Workflow.Runtime.hosting.PersistenceException: escriba 'Microsoft.sharepoint.spweb' en Assembly 'Microsoft.sharepoint, versión = 12.0.0.0, cultura = neutral, publickeyToken = 71e9bce111e9429c' no está marcado como lo es serializable. -> System.Runtime.Serialization.SerializationException: escriba 'Microsoft.sharepoint.spweb' en Assembly 'Microsoft.sharepoint, versión = 12.0.0.0, cultura = neutral, publickeyToken = 71e9bce111e9429c' no está marcado como serializable
El error vino de aquí:
public sealed partial class MyWorkflow : StateMachineWorkflowActivity
{
public SPWorkflowActiviationProperties workflowProperties = new SPWorkflowActivationProperties();
private SPWeb spWebtemp;
private SPWeb spWeb
{
get { return spWebtemp ?? (spWebtemp = workflowProperties.Web); }
}
...
Hay dos publicaciones de blog que encontré:
- ... no está marcado como serializable
- Problema de serialización con Windows Workflow Foundation y SharePoint Workflow
Hay una solución que se encuentra en este problema: No tener objetos miembros complejos como variables globales, pero como variables locales, es decir, declara SPWEB localmente (WorkflowProperties.web) en lugar de a nivel global.
Así que tendría que redeclar a Spweb en cada método que estoy usando, lo que considero bastante feo.
Lo que también probé es esto:
...
[NonSerialized]
private SPWeb spWebtemp;
private SPWeb spWeb
{
get { return spWebtemp ?? (spWebtemp = workflowProperties.Web); }
}
...
==> ¡No más excepción de serialización!
¿Hay implicaciones negativas al usar el NonSerialized
atributo en este campo?
O en otras palabras, ¿cuáles son las implicaciones?
Solución
¿Por qué no lo haces simplemente?
private SPWeb spWeb
{
get { return workflowProperties.Web; }
}
La carga perezosa del objeto spweb ya está manejada por la propiedad de propiedades
Otros consejos
Parece que también funcionaría (el atributo OnDeserialized):
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx
EDITAR
No he probado esto, pero estoy pensando en algo como esto:
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;
}
...
Además, ¿por qué no inicializar el objeto SpwebTemp en el constructor, o no es posible con los flujos de trabajo?