0

I have 2 tables in a database and then using a datamodel in visual studio (datasets), then using 2 classes to store methods and properties of these 2 tables.

I want to store information gathered from a webform into a list but for some reason when trying to add the list to a stateview I get this error:

Type '"".""TableAdapters.""TableAdapter' in Assembly '"", Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

I have already marked the class as serializable but now the tableadapters? Here is my code:

[System.ComponentModel.DataObject]
    [Serializable]
    public class Example
    {
        int _example1 = new int();
        string _example2;
        string _example3; 
        decimal _example4 = new decimal();

        public int example1
        {
            get { return _example1; }
            set { _example1 = value; }
        }

        public string example2
        {
            get { return _example2; }
            set { _example2 = value; }
        }

        public string example3
        {
            get { return _example3; }
            set { _example3 = value; }
        }

        public decimal example4
        {
            get { return _example4; }
            set { _example4 = value; }
        }

        private tblTestTableAdapter _testAdapter = null;
        protected tblTestTableAdapter Adapter
        {
            get
            {
                if (_testAdapter == null)
                    _testAdapter = new tblTestTableAdapter();

                return _testAdapter;
            }
        }

Webform:

 protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
            }
            else
            {
                example = (List<Example>)ViewState["Examples"];
            }
        }

        private List<Example> example;
        public List<Example> GetExample()
        {
            return example;
        } 

        protected void btnRow_Click(object sender, EventArgs e)
        {
            example = new List<Example>(); 
            Example e = new Example();
            e.example1 = Convert.ToInt32(txtE1.Text);
            c.example2 = txtE2.Text;
            c.example3 = txtE3.Text;
            c.example4 = Convert.ToDecimal(txtE4.Text);

            example.Add(e);
            ViewState["Examples"] = example;

            btnRow.Enabled = false;

        }

What is the problem?

user603605
  • 33
  • 5

1 Answers1

0

When marking a class as Serializable every class and dependent object class within it that is exposed externally must all be marked as Serializable. That's because whatever process that is going to perform the serialization will attempt to serialize every public element properly.

FYI, tableadapters are not meant to be exposed publicly because they expose functionality rather than properties and fields. Functionality is not transferred across the serial connection. I would recommend you remove the public nature of the adapter in your example.

Edit 2:
After rereading your code and looking for the documentation for the protection levels of serialized properties, I ran into this link that describes the real problem here. You can't serialize a readonly property (I totally forgot about this), and your tableadapter is property is readonly. Provide it with a set, and it should begin functioning.

Edit: Code sample

[Serializable]
public class MySerializableClass
{
    public MySerializableClass()
    {

    }

    // This string serializes ok
    public string MyStringProperty { get; set; } 

    // Because this property is public in scope it must be serializable
    // because it will be translated at a public scope. This will throw
    // an exception
    public myNonSerializableClass NotSerializableObject { get; set; }   

    // Because this property is private in scope, it will not be included
    // in any serialization calls, so it will not throw an exception, but
    // it will also not be available in whatever remote class calls it.
    private myNonSerializableClass SerializableObject { get; set; } 

    // Because this property object is serializable in code it will be
    // ok to make it public because it will natively serialize itself
    public MyOtherSerializableClass OtherSerializableObject { get; set; }

}
Community
  • 1
  • 1
Joel Etherton
  • 37,325
  • 10
  • 89
  • 104
  • @user603605 - added a code snippet with comments to demonstrate a bit – Joel Etherton Feb 07 '11 at 21:14
  • In what way am i "exposing the tableadapters publicly", I have textboxes in which information is gathered. I want the user to have a choice to either continue adding to the list or continue on. I need the tableadapters so at the end I can insert the list into my database. – user603605 Feb 07 '11 at 21:15
  • @user603605 - Actually I'm giving the wrong reason for the problem, though my answer above is "correct". I'll post an edit with a link. – Joel Etherton Feb 07 '11 at 21:19
  • The link about the read-only property does not apply. It is only relevant for XML serialization. Same goes for public fields, the XML serializer will do public fields and properties, the binary serializer will do all fields not marked as [NonSerialized]. – erikkallen Feb 07 '11 at 23:42
  • @erikkallen - That's true, but in the sample provided here OP is putting the `Example` object into the ViewState. That's XML serialization not binary. – Joel Etherton Feb 08 '11 at 01:21
  • @Joel Etherton: Yes, it is. The viewstate is binary serialized, then Base64-encoded. – erikkallen Feb 08 '11 at 22:10