Адапторите за таблици не са маркирани като сериализируеми?

Имам 2 таблици в база данни и след това използвам модел на данни във визуално студио (набори от данни), след което използвам 2 класа за съхраняване на методи и свойства на тези 2 таблици.

Искам да съхранявам информация, събрана от уеб формуляр в списък, но по някаква причина, когато се опитвам да добавя списъка към изглед на състояние, получавам тази грешка:

Тип '"".""TableAdapters.""TableAdapter' in Assembly '"", Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' не е маркиран като сериализуем.

Вече маркирах класа като сериализуем, но сега адаптерите за таблици? Ето моят код:

[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;
            }
        }

Уеб формуляр:

 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;

        }

Какъв е проблемът?


person user603605    schedule 07.02.2011    source източник


Отговори (1)


Когато маркирате клас като Serializable, всеки клас и зависим клас обект в него, който е изложен външно, трябва да бъдат маркирани като Serializable. Това е така, защото който и процес, който ще извърши сериализацията, ще се опита да сериализира правилно всеки публичен елемент.

FYI, адаптерите за таблици не са предназначени да бъдат излагани публично, защото те разкриват функционалност, а не свойства и полета. Функционалността не се прехвърля през серийната връзка. Бих препоръчал да премахнете публичния характер на адаптера във вашия пример.

Редактиране 2:
След като препрочетох кода ви и потърсих документацията за нивата на защита на сериализирани свойства, попаднах на тази връзка, която описва истинския проблем тук. Не можете да сериализирате свойство само за четене (напълно забравих за това), а вашият адаптер за таблици е свойството да е само за четене. Осигурете му комплект и той трябва да започне да функционира.

Редактиране: Примерен код

[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; }

}
person Joel Etherton    schedule 07.02.2011
comment
@user603605 - добави кодов фрагмент с коментари, за да демонстрира малко - person Joel Etherton; 08.02.2011
comment
По какъв начин излагам табличните адаптери публично, имам текстови полета, в които се събира информация. Искам потребителят да има избор дали да продължи да добавя към списъка или да продължи. Имам нужда от адаптери за таблици, така че накрая да мога да вмъкна списъка в моята база данни. - person user603605; 08.02.2011
comment
@user603605 - Всъщност давам грешна причина за проблема, въпреки че отговорът ми по-горе е правилен. Ще публикувам редакция с линк. - person Joel Etherton; 08.02.2011
comment
Връзката за свойството само за четене не е приложима. Уместно е само за XML сериализация. Същото важи и за публичните полета, XML сериализаторът ще направи публични полета и свойства, двоичният сериализатор ще направи всички полета, които не са маркирани като [NonSerialized]. - person erikkallen; 08.02.2011
comment
@erikkallen - Това е вярно, но в примера, предоставен тук, OP поставя обекта Example във ViewState. Това е XML сериализация, а не двоична. - person Joel Etherton; 08.02.2011
comment
@Joel Etherton: Да, така е. Viewstate е двоично сериализирано, след това Base64-кодирано. - person erikkallen; 09.02.2011