Do you really need a custom CodeDomSerializer?

When you author a new component for .NET for which you want to offer a smooth user experience within the Visual Studio designers, you may find you need to write a few more classes to get it working the way you want. For example, you may need to write a designer for it to customize how it looks and behaves at design time. You may need to write TypeConverters for new types that you add, so that, among other things, they can be configured from the property grid. Maybe you will need to write a UITypeEditor.

Sometimes, you may feel you need to write a custom CodeDomSerializer for the component too. Now, the CodeDomSerializer class hierarchy is definitely designed to be extensible and customizable. In fact, in Whidbey, we have refactored this class hierarchy a bit to expose more common functionality you may need in your custom serializer.

However, before you start writing a custom CodeDomSerializer, you should ask yourself this question: do I really need a custom CodeDomSerializer? After all, very very few of the built in controls and components in Windows Forms have their own custom serializers. Even for the 2-3 components that do, they mostly do only a few lines of work and delegate the rest to the base serializers.

Let me first explain why I believe you should think twice before writing a custom CodeDomSerializer:

  • You may not need it in the first place. I will describe below some ways in which you can customize code generation without writing a custom serializer.
  • Writing a well behaved custom serializer is not trivial. There are many things you need to be careful about. For example, what happens when your component is placed on a Localizable Form? What about if it is in a collection or array? What if someone derives from it and configures some metadata differently? Does your serializer work fine when invoked in a different context than normal code generation – like for undo/redo (in Whidbey)?
  • What if your component is hosted in a design time environment that doesn’t use CodeDom at all? For example, the component may be hosted on a DesignSurface that has a DesignerLoader that uses an xml based serialization scheme (like Xaml). Your custom CodeDomSerializer will not work in this situation, and serialization may not happen as you expect it to.

How then do you customize code generation? Well, it is mostly through the use of metadata. Here are a few possibilities:

  • The DesignerSerializationVisibilityAttribute helps you hide properties that you don’t want serialized from the serializer and also tell it not to serialize the value, but only its content (typically useful for collections).
  • The DefaultValueAttribute and ShouldSerializeBlah methods (where ‘Blah’ is the name of a property) help control under what conditions to serialize a particular property.
  • The LocalizableAttribute controls whether a property is serialized into code or into the resource file when the component is on a Localizable Form.
  • The DesignOnlyAttribute, as the name suggests, can be applied to properties that are only meaningful at design time and don’t need to be serialized as runtime property sets.
  • You can write a TypeConverter for your component (or any new type you have authored) that knows how to convert to InstanceDescriptor to control how objects of the type are instantiated by the serializer.
  • You can also control how objects are serialized into resx files by writing a TypeConverter that can convert to and from string, for example.

Now, I do understand there are legitimate scenarios where you will need to implement custom CodeDomSerializers, and this post is not meant to discourage doing so (in fact, as I said, we have made it easier in Whidbey to write these). However, before you implement one, just remember to consider the issues and suggestions mentioned here. I repeat: for our own components, we have extremely few that implement custom serialization and when they do, the serializer is only a few lines of code and lets the base serializer do most of the work.

See also this post that explains some serialization rules. If you are new to this topic, you will find this excellent article by Shawn Burke very useful.


Comments (17)

  1. Dan AMiga says:

    Well said.

    –Forcing CodeDom on existing components–

    here is a questions – I want to control how existing controls (System.Windows.Forms.Textbox for example) are serialized to code.

    That is – I want to write the code that defines the textbox in the initilize components instead of visual studio.

    It’s "easy" if it’s my control using CodeDomSerializer, but what if it’s a 3rd party control?

  2. rprabhu says:

    You would have to derive from the control and then customize code generation for the derived control. This is the recommended way.

    In Whidbey, you may be able to use metadata substitution to plug in a custom serializer for existing components. But this is a topic for a separate post 🙂

  3. Dan Amiga says:

    "In Whidbey, you may be able to use metadata substitution to plug in a custom serializer for existing components. But this is a topic for a separate post 🙂 "

    This is exactly what I need – metadata substituion techniques in whidbey. how can that be achived? (any links? please post something 🙂 )

  4. rprabhu says:

    In Whidbey, we have made some changes to the TypeDescriptor API to make it possible to dynamically provide/change metadata on components/types. This is done by implementing a TypeDescriptionProvider for a type or component. You can dynamically specify a provider by using TypeDescriptor.AddProvider. If you only need to update an attribute on a component/type, you can use TypeDescriptor.AddAttribute. See this article for more details:

  5. Consider the following code:

    public class MyControl : Control {


  6. jcard says:

    I’m trying to implement a web control that references another control on the page. Visual Studio correctly finds the available instances to select from automatically, but, because it is an object reference, the selected value isn’t serialized to the aspx page and the default serializer doesn’t serialize properties to the InitializeComponent method. I could tell users to data-bind the property t the variable name, but I don’t want to make them do that. So, I’d like to serialize that property, and only that property, to the InitializeComponent method. Since a varible is declared in the .cs file when the control is added, there must be some element of serialization that happens on that file instead of the .aspx page, but I can’t find any references to it in documentation. Am I making this too hard? Do I need a custom CodeDomSerializer?

  7. rprabhu says:

    jcard: Your question seems specific to ASP.NET and I don’t have a lot of context in that area. I would recommend asking it on one of the ASP.NET forums and someone should be able to help you.

  8. Olivier Fermy says:

    I want to make some properties serializable depending on the form context. As i can’t make the attribute DesignerSerializationVisibility depend on the control states, i decided to create a custom CodeDomSerializer which removes the uneeded properties from serialization. It works but i’m unable to prevent the uneeded propreties from being saved to the resources (and applied in InitializeComponent with ApplyResources). And i can’t figure out when the form serializer decides to save the properties to code or to resources. It doesn’t depend on the number of properties or the number of controls to serialize !?!?

  9. rprabhu says:

    Properties marked Localizable(true) are serialized to resources when you set the Localizable property on the form to True.

    If you want to dynamically control serialization of properties, an easier mechanism would be to implement ShouldSerialize methods. This post may be of help:

  10. Olivier Fermy says:

    Thank you for your answer.

    1. Sometimes when a property is marked Localizable(true) (for example the location and size properties) it is either serialized to code or to resources. Depending on the form the serialization for the same control is performed to resource or to code. Is there another rule ?

    2. I have already tried to use ShouldSerializeXXX to remove a property from serialization but it doesn’t work. Here is my code, BackColor and Location are still serialized when i use the UserControl :

    public class UserControl1 : UserControl


    public UserControl1()




    public bool ShouldSerializeBackColor()


    return false;


    public bool ShouldSerializeLocation()


    return false;



  11. rprabhu says:

    You need to override/new up the property XXX for ShouldSerializeXXX method to be picked up.

  12. OS says:

    This is the exact question I am asking myself at the moment….

    I would like the serializer to persist the code into a partial class as the windows forms provider does.

    I would like the serializer to create public instances of member types rather than private.

    I would prefer if the container component does not have a public constructor (I don’t beleive this is possible however).

    I would like the instantiated container to implement the singleton pattern.

    Can any of this be done without a custom serializer?


  13. rprabhu says:

    OS: Comments on your questions:

    1) The default serializers will automatically persist code in the designer owned partial class.

    2) This can be tweaked using the Modifiers property on the component – no need for custom serializer.

    3 & 4) For this kind of thing, you might need to use a custom serializer. However, it might turn out to be a lot of work to get this working, and you might find stuff like undo/redo won’t work very well. I would recommend not going down this route.

  14. OS says:

    Form item 1, I found that the way to get visual studio to persist into partial classes has nothing to do with the codedomserializer, but is simply in how you set up the item template. Program FilesMicrosoft Visual Studio for an example on how it works for the forms designer. I’m certain you knew this but I am providing the above if anyone is following this thread in the future.

    For item 2, can you explain how one would go about this? There is no public Modifiers property on a component. This link ( discusses creating an extender provider to handle this. Is this still the recommended method in 2.0 or is there a simplified way to handle this?


  15. rprabhu says:

    OS: It appears you are working within the context of our root designer. In this case, you don’t need to *create* the Modifiers extender property, but just use the one that is created by the designer infrastructure code.

    You should see the property in the property grid for a component. To access it programmatically, you need to use the TypeDescriptor, something like:

    PropertyDescriptor prop = TypeDescriptor.GetProperties(value)["Modifiers"];

    if (prop != null)


    // blah


  16. Demid says:

    I try to serialize reference to IList.

    I can select lists from drop down list in designer using ReferenceConverter but my IList propery never serialized until its value become null.

    IList _list;


    public IList List


    get { return _list; }

    set { _list = value; }


    class MyListConverter : ReferenceConverter


    public MyListConverter(Type type) : base(type) {}

    protected override bool IsValueAllowed(ITypeDescriptorContext context, object value)


    return value is IList;




  17. rprabhu says:

    Demid: There is no built in serializer for a generic IList. I recommend using a custom type that implements IList instead, and attaching a TypeConverter to it that can convert to/from instance descriptor. See also this post: