XmlSerializer - Была ошибка при отражении типа

Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int:

int x;
x = 10;

В этом примере переменная x является int, и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.

Но когда вы пытаетесь объявить ссылочный тип, произойдет что-то другое. Возьмите следующий код:

Integer num;
num = new Integer(10);

Первая строка объявляет переменную с именем num, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

Во второй строке ключевое слово new используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования . (точка).

Exception, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num. Перед созданием объекта вы получите NullPointerException. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

public void doSomething(SomeObject obj) {
   //do something to obj
}

В этом случае вы не создаете объект obj, скорее предполагая, что он был создан до вызова метода doSomething. К сожалению, этот метод можно вызвать следующим образом:

doSomething(null);

В этом случае obj имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException, потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.

Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething может быть записано как:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj != null) {
       //do something
    } else {
       //do something else
    }
}

Наконец, Как определить исключение & amp; причина использования Трассировки стека

326
задан Ryan Kohn 19 September 2013 в 03:11
поделиться

9 ответов

Посмотрите на внутреннее исключение, которое Вы получаете. Это скажет Вам, какое поле/свойство это испытывает затруднения при сериализации.

можно исключить поля/свойства из XML-сериализации путем украшения их эти [XmlIgnore] атрибут.

я не думаю, что XmlSerializer использование эти [Serializable] атрибут, таким образом, я сомневаюсь относительно этого, является проблемой.

408
ответ дан participant 23 November 2019 в 00:51
поделиться

Я использовал NetDataSerialiser класс для сериализации моих доменных классов. Класс .

NetDataContractSerializer доменные классы совместно используются клиентом и сервером.

0
ответ дан Peter Mortensen 23 November 2019 в 00:51
поделиться

Также обратите внимание, что Вы не можете сериализировать средства управления пользовательским интерфейсом и что любой объект, который Вы хотите передать на буфер обмена, должен быть сериализуемым иначе, это не может быть передано через другим процессам.

0
ответ дан Phil Wright 23 November 2019 в 00:51
поделиться

Я также думал, что сериализуемый атрибут должен был быть на объекте, но если я не полный новичок (я в середине конца ночного кодирования сессии), следующие работы от SnippetCompiler:

using System;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.Xml.Serialization;

public class Inner
{
    private string _AnotherStringProperty;
    public string AnotherStringProperty 
    { 
      get { return _AnotherStringProperty; } 
      set { _AnotherStringProperty = value; } 
    }
}

public class DataClass
{
    private string _StringProperty;
    public string StringProperty 
    { 
       get { return _StringProperty; } 
       set{ _StringProperty = value; } 
    }

    private Inner _InnerObject;
    public Inner InnerObject 
    { 
       get { return _InnerObject; } 
       set { _InnerObject = value; } 
    }
}

public class MyClass
{

    public static void Main()
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
            TextWriter writer = new StreamWriter(@"c:\tmp\dataClass.xml");
            DataClass clazz = new DataClass();
            Inner inner = new Inner();
            inner.AnotherStringProperty = "Foo2";
            clazz.InnerObject = inner;
            clazz.StringProperty = "foo";
            serializer.Serialize(writer, clazz);
        }
        finally
        {
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }
    }

}

я предположил бы, что XmlSerializer использует отражение по общественным собственностям.

2
ответ дан Darren 23 November 2019 в 00:51
поделиться

Все объекты в графике сериализации должны быть сериализуемыми.

С тех пор XMLSerializer черный ящик, проверьте эти ссылки, если Вы хотите отладить далее в процесс сериализации..

Изменение, где Выводы XmlSerializer Временные блоки

, КАК К: Отладка в.NET XmlSerializer Сгенерированный блок

5
ответ дан Dave New 23 November 2019 в 00:51
поделиться

Помните, что сериализированные классы должны иметь значение по умолчанию (т.е. без параметров) конструкторы. Если у Вас нет конструктора вообще, это прекрасно; но если у Вас будет конструктор с параметром, необходимо будет добавить по умолчанию также.

109
ответ дан Jeremy McGee 23 November 2019 в 00:51
поделиться

Также знайте, что XmlSerializer не может сериализировать абстрактные свойства.. Посмотрите мой вопрос здесь (который я добавил код решения к)..

Сериализация XML и Наследованные Типы

7
ответ дан Community 23 November 2019 в 00:51
поделиться

Я обнаружил, что класс Dictionary в .Net 2.0 не сериализуется с помощью XML, но хорошо сериализуется при использовании двоичной сериализации.

Я нашел работу около здесь .

4
ответ дан 23 November 2019 в 00:51
поделиться

Если вам нужно обрабатывать определенные атрибуты (например, словарь или любой класс), вы можете реализовать интерфейс IXmlSerialiable , который предоставит вам больше свободы за счет более подробного кодирования ].

public class NetService : IXmlSerializable
{
    #region Data

        public string Identifier = String.Empty;

        public string Name = String.Empty;

        public IPAddress Address = IPAddress.None;
        public int Port = 7777;

    #endregion

    #region IXmlSerializable Implementation

        public XmlSchema GetSchema() { return (null); }

        public void ReadXml(XmlReader reader)
        {
            // Attributes
            Identifier = reader[XML_IDENTIFIER];
            if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
            if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
        }

        public void WriteXml(XmlWriter writer)
        {
            // Attributes
            writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
            writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
            writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
        }

        private const string XML_IDENTIFIER = "Id";

        private const string XML_NETWORK_ADDR = "Address";

        private const string XML_NETWORK_PORT = "Port";

    #endregion
}

Есть интересная статья , в которой показан элегантный способ реализации изощренного способа «расширения» XmlSerializer.


В статье говорится:

IXmlSerializable описан в официальной документации, но в документации указано, что он не предназначен для публичного использования и не предоставляет никакой дополнительной информации. Это указывает на то, что группа разработчиков хотела оставить за собой право изменять, отключать или даже полностью удалять эту возможность расширения в будущем. Однако до тех пор, пока вы готовы принять эту неопределенность и иметь дело с возможными изменениями в будущем, нет никаких причин, по которым вы не можете ею воспользоваться.

Поэтому я предлагаю реализовать собственные классы IXmlSerializable , чтобы избежать слишком сложных реализаций.

... может быть просто реализовать наш собственный класс XmlSerializer с использованием отражения.

5
ответ дан 23 November 2019 в 00:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: