Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Сериализация


Автор: STRELOKBMSTU 25.12.2009, 14:11
Есть собственный класс:

Код

    [Serializable]
    public sealed class MessageObject
    {
            private Type _messageType;
            private IPEndPoint _ip;


            public enum Type
            { 
              Register,
              Unregister,
              InputMessage
            }
                       
            public Type MessageType
            {
                get { return _messageType; }
                set { _messageType = value; }
            }

            public IPEndPoint IP
            {
                get { return _ip; }
                set { _ip = value; }
            }

        
            public MessageObject()
            { }
        }


при попытке его сериализации XmlSerializer'ом вылетает Exception:

Код

There was an error reflecting type 'WindowsFormsApplication3.MessageObject'.

"Cannot serialize member 'WindowsFormsApplication3.MessageObject.IP' of type 'System.Net.IPEndPoint', see inner exception for more details."}


{"System.Net.IPEndPoint cannot be serialized because it does not have a parameterless constructor."}



Может каким-нибудь атрибутом пометить эндпоинт или еще что-то сделать, чтоб его засериализовать???

Автор: tol05 25.12.2009, 14:18
можно непосредственно реализовать интерфейс ISerializable и в нем вручную серилизовывать\десерилизовывать это поле

второй вариант - задать тип свойства строка, наример, а в get\set преобразовывать сроку в IPEndPoint и обратно

Автор: STRELOKBMSTU 25.12.2009, 14:56
Погодь, что-то не до конца понял... Второй метод вроде попроще, но у свойства получается должен быть всегда тип string??? Можно поподробнее, если получится, с кодом? smile 

Автор: tol05 25.12.2009, 15:19
даже кода не нужно. Вам со свойством 
Код

  public IPEndPoint IP
            {
                get { return _ip; }
                set { _ip = value; }
            }
и работать нужно, и серилизовывать его?
Ну так сделайте два свойства. Одно с типом string - для серилизации\десерилизации, а второе (с аттрибутом XmlIgnore) - для работы. 
оба свойтсва будут работать с одним и тем же полем 
Код

 private IPEndPoint _ip;

...
Код

public string serilizedIP
            {
                get { //делаем из поля _ip сроку }
                set { //делаем из строки значение для _ip }
            }
[XmlIgnore]
public IPEndPoint IP
            {
                get { return _ip; }
                set { _ip = value; }
            }

Автор: STRELOKBMSTU 25.12.2009, 15:30
Вот, добрались до атрибутов, с утра по ним инфу копаю, у меня нету [XmlIgnore]...  Как его подключить, в каком он namespace?

Автор: tol05 25.12.2009, 15:33
System.Xml.Serialization
странно. как Вы с XmlSerializer работаете тогда? он в том же намеспейсе находится.

Автор: STRELOKBMSTU 25.12.2009, 17:08
Пасиб, в классе не использовал этот наймспейс.

А private поля тоже сериализуются? Сейчас у меня код выглядит так, но значение не передается все равно...


Код

[Serializable]
    public sealed class MessageObject
    {
            private Type _messageType;
            private IPAddress _ip;
            private int _port;
            public enum Type
            { 
              Register,
              Unregister,
              InputMessage
            }
                       
            public Type MessageType
            {
                get { return _messageType; }
                set { _messageType = value; }
            }

        [XmlIgnore]
        public IPEndPoint IP
        {
            get
            {
                return new IPEndPoint(_ip, _port);
            }
            set
            {
                _ip = value.Address;
                _port = value.Port;
            }
        }
        
            public MessageObject()
            { }
        }

Автор: tol05 25.12.2009, 17:59
Серилизатор XML серилизует только public члены класса, и только те, которые не помечены аттрибутом  [XmlIgnore]
Я не вижу второго свойства, о котором мы говорили. Где оно?

вот код, короче
Код

public sealed class MessageObject
    {
        private Type _messageType;
        private IPAddress _ip;
        private int _port;
        
        public enum Type
        {
            Register,
            Unregister,
            InputMessage
        }

        public Type MessageType
        {
            get { return _messageType; }
            set { _messageType = value; }
        }

        [XmlIgnore]
        public IPEndPoint IP
        {
            get
            {
                return new IPEndPoint(_ip, _port);
            }
            set
            {
                _ip = value.Address;
                _port = value.Port;
            }
        }

        [XmlElement(ElementName = "IP")]
        public string SerializableIP
        {
            get
            {
                return string.Format("ip={0}_port={1}", _ip, _port);
            }
            set
            {
                //добавить проверки на кол-во элементов массива и try-catch на парсинг
                
                string[] inputValues = value.Split('_');
                _ip = IPAddress.Parse(inputValues[0]);
                _port = Int32.Parse(inputValues[1]);
            }
        }

        public MessageObject(){ }
    }

Автор: STRELOKBMSTU 25.12.2009, 18:06
В интернете почитал вроде как для сериализации EndPoint используется тип SocketAddress, но с ним те же косяки были... пробовал так:

Код

[Serializable]
    public sealed class MessageObject
    {
        private Type _messageType;
        private SocketAddress _ip;

        public enum Type
        {
            Register,
            Unregister,
            InputMessage
        }

        public Type MessageType
        {
            get { return _messageType; }
            set { _messageType = value; }
        }

        public SocketAddress IP
        {
            get { return _ip; }
            set { _ip = value;}
        }


        [XmlIgnore]
        public IPEndPoint IPEndPoint
        {
            get 
            {
              IPEndPoint endpoint = new IPEndPoint(0, 0);
              return (IPEndPoint)endpoint.Create(_ip);
            }
            set { _ip = value.Serialize(); }
        }


        public MessageObject()
        { }
    }


но с ним те же проблемы были, сейчас попробую ваш метод, надеюсь поможет... smile 

Автор: Heinzz 25.12.2009, 18:09
Цитата(STRELOKBMSTU @  25.12.2009,  17:08 Найти цитируемый пост)
А private поля тоже сериализуются

нет

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)