Как управлять исключениями сериализации XML для enum - PullRequest
1 голос
/ 17 сентября 2011

Я использую сериализацию XML для создания файла в формате, специфичном для другого приложения. Одним из требований является то, что все логические значения должны быть представлены как 1 или 0. Я рассмотрел некоторые возможности, в том числе struct , чтобы легко и без проблем справиться с этим. В настоящее время я ищу другое место, которое должно использовать enum.

public enum BoolEnum
{
    [XmlEnum("0")]
    False = 0,
    [XmlEnum("1")]
    True = 1
}

Пока что это прекрасно работает и намного чище. НО (!) Я также пытаюсь сделать десериализацию легкой, и я просто хотел бы иметь возможность обрабатывать ошибки. Если я создаю недопустимый тег:

<invalid>2</invalid>

чтобы быть десериализованным как BoolEnum, я получаю исключение InvalidOperationException внутри другого исключения InvalidOperationException. Как я могу поймать это исключение в перечислении?


Добавление:

Функция десериализации:

static void Deserialize<T>(out T result, string sourcePath) where T : class
{
    FileStream fileStream = null;

    try
    {
        fileStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read);
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        result = xmlSerializer.Deserialize(fileStream) as T;
    }
    finally
    {
        if (fileStream != null)
            fileStream.Close();
    }
}

Десериализованный объект:

public class Test
{
    [XmlElement("someboolvalue")
    public BoolEnum SomeBoolValue { get; set; }
}

Ответы [ 2 ]

3 голосов
/ 17 сентября 2011

Я просто хотел бы иметь возможность обрабатывать ошибки

Атрибуты можно использовать для предоставления определенных свойств сериализации Xml и скрытия от нее других свойств. Точно так же вы можете выставлять определенные свойства, которые будут видны через Intellisense, и скрывать другие.

Вы можете воспользоваться этим фактом, чтобы использовать другой тип свойства, видимый в коде, из базовой сериализации. Это позволит вам использовать bool в коде и int в сериализации.

Если вы выберете этот маршрут, вы можете добавить собственный код сериализации для обработки этого случая в методах getter / setter свойства int. Э.Г.

[XmlIgnore]
public bool SomeValue { get; set; }

[EditorBrowsable(EditorBrowsableState.Never)]
[XmlElement("SomeValue")]
public int SomeValueForSerialization
{
    get
    {
        return SomeValue ? 1 : 0;
    }
    set
    {
        SomeValue = value != 0;
        // Or do strict validation, and throw whatever exception you'd like.
        // Preferably one the serializer will already throw, tho :)
    }
}
0 голосов
/ 17 сентября 2011

Я обычно предпочитаю сохранять сложное постоянство как отдельную особенность класса.

Я использую комбинацию XElement и методы расширения, чтобы сделать постоянство ясным и лаконичным, например:

public static int AsZeroOrOneElelementNamed(this bool theBool, string name)
{
    return new XElement( name, theBool ? 1 : 0 ) ;
}

тогда, в вашем типе:

public XElement AsXml( )
{
    return new XElement(@"ThisThing",
        _myBoolean.AsZeroOrElementNamed(@"MyBoolean"),
        _myString.AsElementNamed(@"MyString"));
}

Это избавляет от беспорядка атрибутов XML, что делает его более ясным и чистым и оставляет аспект постоянства методу, единственной ответственностью которого является сериализация.

Но для очень простой настойчивости, например где я не загромождаю свои типы любыми атрибутами, тогда я использую встроенное постоянство.

...