Property assignment causes strange designer-generated code

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?bWljaGFlbCBzb3JlbnM=?=

    #1

    Property assignment causes strange designer-generated code

    Yesterday Visual Studio gave me a strange error both at compiletime and at
    designtime that had no obvious connection to anything I had changed recently.
    After some effort tracking down the problem I discovered first a workaround,
    then the real cause of the problem. I would like to understand why what I am
    doing is frowned upon by Visual Studio and how to do this properly.

    My application is in one solution; supporting libraries including custom
    controls in another. I am using C# in VS2008 and compiling to .NET 2.0 on
    WinXP.

    These are the compiletime errors:
    ############### ############
    Error 1 Invalid Resx file. Type could not be read from the data in line
    169, position 5. The type's internal structure may have changed. Either
    implement ISerializable on the type or provide a type converter that can
    provide a more reliable conversion format, such as text or an array of bytes.
    The conversion exception was: The constructor to deserialize an object of
    type 'CleanCodeContr ols.Support.Con nectionDetails' was not found. File:
    MainForm.resx

    Error 2 SerializationEx ception: Type could not be read from the data in
    line 169, position 5. The type's internal structure may have changed.
    Either implement ISerializable on the type or provide a type converter that
    can provide a more reliable conversion format, such as text or an array of
    bytes. The conversion exception was: The constructor to deserialize an
    object of type 'CleanCodeContr ols.Support.Con nectionDetails' was not found.
    XmlException: Type could not be read from the data in line 169, position 5.
    The type's internal structure may have changed. Either implement
    ISerializable on the type or provide a type converter that can provide a more
    reliable conversion format, such as text or an array of bytes. The
    conversion exception was: The constructor to deserialize an object of type
    'CleanCodeContr ols.Support.Con nectionDetails' was not found. Line 169,
    position 5.
    ############### ############

    The visual designer manifests essentially the same error:
    ############### ############
    The constructor to deserialize an object of type
    'CleanCodeContr ols.Support.Con nectionDetails' was not found.
    ############### ############

    These errors appeared because of this designer-generated statement in
    MainForm.Design er.cs...
    ############### ############
    new
    CleanCodeContro ls.Support.Conn ectionDetailsCo llection().Add( ((CleanCodeCont rols.Support.Co nnectionDetails )(resources.Get Object("leftSql Editor.Configur ationList"))));
    ############### ############

    That line was embedded in a set of statements initializing a custom control
    inside InitializeCompo nent; here's some context. Instead of assigning to the
    ConfigurationLi st property it created this unusual line.
    ############### ############
    this.leftSqlEdi tor.AutoExecute Mode = false;
    this.leftSqlEdi tor.AutoHighlig htMode = false;
    this.leftSqlEdi tor.CommandTime out = 60;
    new
    CleanCodeContro ls.Support.Conn ectionDetailsCo llection().Add( ((CleanCodeCont rols.Support.Co nnectionDetails )(resources.Get Object("leftSql Editor.Configur ationList"))));
    this.leftSqlEdi tor.ContainerTe st = false;
    this.leftSqlEdi tor.CsvPath = ".";
    this.leftSqlEdi tor.DbConfigura tionName = "--";
    this.leftSqlEdi tor.DiagLabel = "LeftSqlEditor" ;
    this.leftSqlEdi tor.Dock = System.Windows. Forms.DockStyle .Fill;
    this.leftSqlEdi tor.LocalMode = false;
    ############### ############

    Corresponding to this was a section in the MainForm.resx file:
    ############### ############
    <data name="leftSqlEd itor.Configurat ionList"
    mimetype="appli cation/x-microsoft.net.o bject.binary.ba se64">
    <value>--- encoded binary data here --- </value>
    </data>
    ############### ############

    By deleting the line in MainForm.Design er.cs and deleting the <dataelement
    in the MainForm.resx file, I could then compile successful and open the form
    in visual designer. However, everytime I re-display the form in the visual
    designer those code chunks are inserted again.

    I digged deeper to determine why those lines were being generated all of a
    sudden, because I had not changed anything related to the serialization or
    structure of ConnectionDetai ls. I traced it to the line indicated with arrows
    below (the ConfigurationLi st assignment inside this ContainerTest property)
    of my SqlEditor custom control. leftSqlEditor is an instance of SqlEditor.
    Removing the assignment to the ConfigurationLi st property removes the
    generation of the above offending code by the visual designer.

    ############### ############
    public bool ContainerTest
    {
    get { return containerTest; }
    set
    {
    containerTest = value;

    // signal to fill unbound DataGridView
    dataGridView.Co ntainerTest = containerTest;

    // provide a default connection to get bound data as well
    >>>> ConfigurationLi st = new ConnectionDetai lsCollection {
    new ConnectionDetai ls
    {
    ConfigName = "sqlExpress ",
    ConnectionStrin g =
    @"Data Source=.\SQLEXP RESS;Initial
    Catalog=Adventu reWorks;"+
    @"Integrated Security=True;P ersist Security
    Info=True",
    DbType = ConnectionStrin gManager.DBType s.SqlServer
    }
    };

    DbConfiguration Name = "sqlExpress ";
    }
    }
    private bool containerTest = false;

    public ConnectionDetai lsCollection ConfigurationLi st
    {
    get { return configurationLi st; }
    set
    {
    configurationLi st = value;
    UpdateForChange dConfigList();
    }
    }
    private static ConnectionDetai lsCollection configurationLi st;

    ############### ############


    Here are the relevant code highlights of the object that is apparently
    having serialization problems, though this code has been working fine even
    with the Properties/Settings page for over 6 months. I can, for instance, go
    to the Properties/Settings page of the application, click on the ellipsis for
    this setting, and VS invokes a collection editor to allow manipulation of the
    collection without complaint. My understanding was that this uses the
    serialization in question.

    ############### ############
    namespace CleanCodeContro ls.Support
    {
    public class ConnectionDetai lsCollection : Collection<Conn ectionDetails>
    {
    // empty
    }


    [Serializable]
    public class ConnectionDetai ls : ICloneable, ISerializable
    {

    public ConnectionDetai ls(string configName) { this.configName =
    configName; }

    public ConnectionDetai ls() { }

    public void GetObjectData(S erializationInf o info, StreamingContex t context)
    {
    info.AddValue(" ConfigName", configName);
    info.AddValue(" ConnectionStrin g", connectionStrin g);
    info.AddValue(" DbType", dbType);
    info.AddValue(" RememberPasswor d", rememberPasswor d);
    info.AddValue(" Description", description);
    }
    }
    }
    ############### ############


    So why does my particular sequence of code generate these misbehaving lines
    of code, and why are they misbehaving? Or to cut to the chase: what could I
    do to fix this?


  • =?Utf-8?B?bWljaGFlbCBzb3JlbnM=?=

    #2
    RE: Property assignment causes strange designer-generated code

    Thanks for the information, but it did not fix the issue.

    Adding the first item:
    [DesignerSeriali zationVisibilit y(DesignerSeria lizationVisibil ity.Content)]

    changed the generated code from:
    new
    CleanCodeContro ls.Support.Conn ectionDetailsCo llection().Add( ((CleanCodeCont rols.Support.Co nnectionDetails )(resources.Get Object("leftSql Editor.Configur ationList"))));
    to:

    this.leftSqlEdi tor.Configurati onList.Add(((Cl eanCodeControls .Support.Connec tionDetails)(re sources.GetObje ct("leftSqlEdit or.Configuratio nList"))));

    Next, I added this serialization constructor (with a couple modifications to
    your code to get it to compile):

    protected ConnectionDetai ls(Serializatio nInfo info, StreamingContex t
    context)
    {
    configName = info.GetString( "ConfigName ");
    connectionStrin g = info.GetString( "ConnectionStri ng");
    dbType = (ConnectionStri ngManager.DBTyp es)Enum.Parse(
    typeof(Connecti onStringManager .DBTypes),
    info.GetString( "DbType"));
    rememberPasswor d = info.GetBoolean ("RememberPassw ord");
    description = info.GetString( "Descriptio n");
    }

    And finally I added the SetType at the top of GetObjectData.

    Now attempting to open the form in the designer yields this error:

    "Method 'CleanCodeContr ols.Support.Con nectionDetailsC ollection.Add' not
    found. "

    My ConnectionDetai lsCollection class, as a reminder is just this empty class
    definition:

    public class ConnectionDetai lsCollection : Collection<Conn ectionDetails>
    {
    // empty
    }

    So are we getting closer to a solution? My understanding of the connections
    for serialization is weak.

    Comment

    • Linda Liu[MSFT]

      #3
      RE: Property assignment causes strange designer-generated code

      Hi Michael,

      Thank you for your reply!
      Next, I added this serialization constructor (with a couple modifications
      to your code to get it to compile):

      I didn't know the type of the DbType property and I assumed it as the type
      of String. Thank you for showing us how you correct this line of code!
      Now attempting to open the form in the designer yields this error:
      "Method 'CleanCodeContr ols.Support.Con nectionDetailsC ollection.Add' not
      found. "

      Please delete the custom control from the Form and delete the item
      "leftSqlEditor. ConfigurationLi st" from the form.resx file first. Re-build
      the project and re-open the form in the designer and add the custom control
      onto the form to see if the problem still exists.

      Sincerely,
      Linda Liu
      Microsoft Online Community Support

      Delighting our customers is our #1 priority. We welcome your comments and
      suggestions about how we can improve the support we provide to you. Please
      feel free to let my manager know what you think of the level of service
      provided. You can send feedback directly to my manager at:
      msdnmg@microsof t.com.

      This posting is provided "AS IS" with no warranties, and confers no rights.

      Comment

      • =?Utf-8?B?bWljaGFlbCBzb3JlbnM=?=

        #4
        RE: Property assignment causes strange designer-generated code

        Rebuilding as you indicated seems to have cleared up the issue.
        As a final question on this topic, could you point me to the MSDN pages that
        describe these pieces necessary for proper serialization?

        I looked through "Introducin g XML Serialization"
        (http://msdn.microsoft.com/en-us/libr...hh(VS.80).aspx)
        but I cannot find where it talks about any of the three points you itemized
        to fix my problem.

        Thanks!

        Comment

        • Linda Liu[MSFT]

          #5
          RE: Property assignment causes strange designer-generated code

          Hi Michael,

          Thank you for your reply!

          As for the first point, properties that do not have a
          DesignerSeriali zationVisibilit yAttribute will be treated as though they
          have a DesignerSeriali zationVisibilit yAttribute with a value of Visible.
          For a property of type collection, a private variable of type collection
          will be created and initialized with the items configured at design time
          first and then assigned to the public collection property within the
          InitializeCompo nent method.

          In your scenario, you configure the ConfigurationLi st property within the
          set accessor of the ContainerTest property, so the form designer doesn't
          know which property the private variable should be assigned to. At this
          time, we can specify a DesignerSeriali zationVisibilit yAttribute with a
          value of Content to address the problem.

          The following MSDN document may help:
          'How to: Serialize Collections of Standard Types with the
          DesignerSeriali zationVisibilit yAttribute'
          http://msdn.microsoft.com/en-us/library/ms171833.aspx

          As for the second point, you implement the ISerializable interface for the
          ConnectionDetai ls class, so the value of this property will be serialize
          and stored in the form's resx file. When the form is re-opened, a design
          time error occurs. So it's obvious that something is wrong when the form
          designer is trying to construct instances of the
          ConnectionDetai lsCollection class.

          There's a comment "The ISerializable interface implies a constructor with
          the signature constructor (SerializationI nfo information, StreamingContex t
          context). " in the following MSDN document that explains this exactly:
          http://msdn.microsoft.com/en-us/libr...zation.iserial
          izable.aspx

          As for the third point, after I configured the ConfigurationLi st property
          in the designer and compile the project, I found that the value under the
          Type column of the item "leftSqlEditor. ConfigurationLi st" within the
          form.resx is null. So the type of the resource item is missing.

          The sample in the
          "http://msdn.microsoft. com/en-us/library/system.runtime. serialization.i seria
          lizable.aspx" shows that we should call the SerializationIn fo.SetType
          method to set the Type of the object to serialize in the
          ISerializable.G etObjectData implementation.

          Hope this helps.
          If you have any question, please feel free to let me know.

          Sincerely,
          Linda Liu
          Microsoft Online Community Support

          Delighting our customers is our #1 priority. We welcome your comments and
          suggestions about how we can improve the support we provide to you. Please
          feel free to let my manager know what you think of the level of service
          provided. You can send feedback directly to my manager at:
          msdnmg@microsof t.com.

          This posting is provided "AS IS" with no warranties, and confers no rights.

          Comment

          • =?Utf-8?B?bWljaGFlbCBzb3JlbnM=?=

            #6
            RE: Property assignment causes strange designer-generated code

            Thank you, Linda. The information you provided has been very enlightening!

            Comment

            • Linda Liu[MSFT]

              #7
              RE: Property assignment causes strange designer-generated code

              You're welcome, Michael!

              If you have any other questions in the future, please don't hesitate to
              contact us. It's always our pleasure to be of assistance.

              Have a nice day!

              Sincerely,
              Linda Liu
              Microsoft Online Community Support

              Delighting our customers is our #1 priority. We welcome your comments and
              suggestions about how we can improve the support we provide to you. Please
              feel free to let my manager know what you think of the level of service
              provided. You can send feedback directly to my manager at:
              msdnmg@microsof t.com.

              This posting is provided "AS IS" with no warranties, and confers no rights.

              Comment

              Working...