Serialization with CodeDomSerializer - How to Initialize Manager Object?
Asked Answered
H

1

1

There are numerous examples on the web that show how to use the CodeDomSerializer. Most of them show how to override the Serialize and Deserialize methods of that class. The problem is that this Serialize method takes a manager argument of type IDesignerSerializationManager. I cannot figure out how to create an instance of that type...

Here's what I tried:

var root = new Form();
root.Controls.Add(new TextBox()
{
   Text = "hello"
});

Type rootSerializerType = Type.GetType("System.ComponentModel.Design.Serialization.RootCodeDomSerializer, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", true);

var rootSerializer = Activator.CreateInstance(
   rootSerializerType,
   BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
   null,
   null,
   null) as CodeDomSerializer;

IDesignerSerializationManager manager = new DesignerSerializationManager();
var serializationResult = (CodeTypeDeclaration)rootSerializer.Serialize(manager, root);

Because my manager object is not properly initialized, when I call the Serialize method as shown above, this exception is thrown:

[System.InvalidOperationException] "This method cannot be invoked because the serialization manager does not have an active serialization session."

I have googled and checked StackOverflow and I can't find any help on how to properly initialize the manager object ahead of my .Serialize invokation.

Any ideas?

Herewith answered 14/11, 2017 at 16:30 Comment(1)
Take a look at this post, you may find it useful: Hosting Windows Forms Designer - Serialize and Deserialize designer at runtime.Errata
G
2

You need to create the section. Change last two lines to:

DesignerSerializationManager manager = new DesignerSerializationManager();
using (var session = manager.CreateSession())
{
    var serializationResult = (CodeTypeDeclaration)rootSerializer.Serialize(manager, root);
    // handle the result here
}

Use either the concrete class DesignerSerializationManager or var, because the IDesignerSerializationManager interface does not have the CreateSession method.

Gearing answered 14/11, 2017 at 16:47 Comment(8)
That makes sense. But when I follow your instructions I get a "Object reference not set to an instance of an object." exception at the call to the .Serialize(manager, root) method. Any ideas?Herewith
Yeah. The root (second parameter) should be initialized before the callGearing
Yes, the root in fact contains a fully-baked object of type System.Windows.Forms.Form. I checked in the debugger and manager and rootSerializer also are set to instances of an object.Herewith
Strange. When I test with "object root = new object();" it runs just fine. Could you try it please?Gearing
OK, I tried with "Form root = new Form();" then I added a TextBox control to its controls collection along with a TextBox Text string value. The code doesn't throw an exception (which means that my root object was the problem)--but I also cannot prove that it works because the serializationResult seems to have no CodeDom information in it... I was expecting to see C# code returned from the Serialization call... If I can see that working, I will be able to mark your answer as correct. Thanks.Herewith
Cast the the result to CodeTypeDeclaration. I updated my answer to reflect this changeGearing
I already had done that cast. Of all of the properties and collections exposed by the serializationResult object, I see nothing that looks like C# code. So I cannot confirm that this code works. As your final comments, can you share with me how I would see that C# code or anything at all that shows successful serialization results? (In minutes I will amend my original question with code showing the Form object I am trying to serialize.)Herewith
I need a way to confirm that the serialization works. Ideally, I want to convert CodeDom results to C# code, such as here: learn.microsoft.com/en-us/dotnet/framework/… -- but I don't want to stray from my original question. I just want to know that the CodeDom is populated with the Form object, TextBox, and the "hello" value for the TextBox.Text property. If I can see that, I know your manager object is working properly. Thanks.Herewith

© 2022 - 2024 — McMap. All rights reserved.