Ma3yTa Ma3yTa - 2 years ago 172
C# Question

anonymous method closures that capture the environment are not serializable

I am getting error


Exception: anonymous method closures that capture the environment are not serializable, consider removing environment capture or using a reflection serialization surrogate: assistant.dialogs.Forms.SupportRequest+<>c__DisplayClass7_0'


when try to set inner property in Chain.

Could you please help? Thanks

My code:

public enum SystemSelection { SharePoint, BizTalk, Azure, Office365 };
public enum RequestType { Bug, SupportRequest, Question };
public enum Importance { Blocking, High, Medium, Low };

[Serializable]
class Declaration
{
public string Type;
public string Amount;
public string Date;

public static IForm<Declaration> BuildForm()
{
return new FormBuilder<Declaration>()
.Message("Add a declaration")
.Build();
}
}

[Serializable]
class SupportRequest
{

public SystemSelection? SystemSelection;
public RequestType? RequestType;
public Importance? Importance;

public Declaration Declaration;

public static IForm<SupportRequest> BuildForm()
{
return new FormBuilder<SupportRequest>()
.Message("Welcome to the simple support bot!")
.AddRemainingFields()
.Build();
}

internal static IDialog<SupportRequest> MakeRootDialog3()
{
SupportRequest t = null;
var dlg = Chain.ContinueWith(FormDialog.FromForm(SupportRequest.BuildForm),
async (context, res) =>
{
t = await res;
return Chain.ContinueWith<Declaration, SupportRequest>(FormDialog.FromForm(Declaration.BuildForm),
async (context2, res2) =>
{
t.Declaration = await res2;
return Chain.Return(t);
});
});

return dlg;
}
}

Answer Source

This is expected since anonymous method are not serializable and per the docs you need to ensure all the dialogs are serializable:

Ensure that all dialogs are serializable. This can be as simple as using the [Serializable] attribute on your IDialog implementations. However, be aware that anonymous method closures are not serializable if they reference their outside environment to capture variables. The Bot Framework supports a reflection-based serialization surrogate to help serialize types that are not marked as serializable.

You will have to replace the ResumeAfter<T> continuation you are defining as an anonymous method with a non-anonymous one.

Alternatively, you can try using registering the Reflection Serialization Surrogate by adding it to the Autofac container. In your global.asax, try adding this code:

Conversation.UpdateContainer(builder =>
{   
    builder.RegisterModule(new ReflectionSurrogateModule());
});
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download