Как я сериализую значение enum как int?

Я хочу сериализовать значение enum как int, но я получаю только имя.

Вот мой (пример) класс и перечисление:

public class Request {
    public RequestType request;
}

public enum RequestType
{
    Booking = 1,
    Confirmation = 2,
    PreBooking = 4,
    PreBookingConfirmation = 5,
    BookingStatus = 6
}

И код (чтобы быть уверенным, что я не ошибаюсь)

Request req = new Request();
req.request = RequestType.Confirmation;
XmlSerializer xml = new XmlSerializer(req.GetType());
StringWriter writer = new StringWriter();
xml.Serialize(writer, req);
textBox1.Text = writer.ToString();

Этот ответ (на другой вопрос), похоже, указывает, что перечисления должны быть сериализованы для ints по умолчанию, но, похоже, это не так. Вот мой вывод:

<?xml version="1.0" encoding="utf-16"?>
<Request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <request>Confirmation</request>
</Request>

Мне удалось сериализовать как значение, поместив атрибут "[XmlEnum (" X ")] на каждое значение, но это просто кажется неправильным.

Ответ 1

В большинстве случаев людям нужны имена, а не ints. Вы можете добавить свойство прокладки для этой цели?

[XmlIgnore]
public MyEnum Foo {get;set;}

[XmlElement("Foo")]
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
public int FooInt32 {
    get {return (int)Foo;}
    set {Foo = (MyEnum)value;}
}

Или вы можете использовать IXmlSerializable, но это очень много работы.

Ответ 2

Самый простой способ - использовать атрибут [XmlEnum] следующим образом:

[Serializable]
public enum EnumToSerialize
{
    [XmlEnum("1")]
    One = 1,
    [XmlEnum("2")]
    Two = 2
}

Это приведет к сериализации в XML (скажем, что родительский класс - CustomClass):

<CustomClass>
  <EnumValue>2</EnumValue>
</CustomClass>

Ответ 3

Пожалуйста, ознакомьтесь с приведенной ниже программой Console Application для интересного способа достижения того, что вы ищете, с помощью DataContractSerializer:

using System;
using System.IO;
using System.Runtime.Serialization;

namespace ConsoleApplication1
{
    [DataContract(Namespace="petermcg.wordpress.com")]
    public class Request
    {
        [DataMember(EmitDefaultValue = false)]
        public RequestType request;
    }

    [DataContract(Namespace = "petermcg.wordpress.com")]
    public enum RequestType
    {
        [EnumMember(Value = "1")]
        Booking = 1,
        [EnumMember(Value = "2")]
        Confirmation = 2,
        [EnumMember(Value = "4")]
        PreBooking = 4,
        [EnumMember(Value = "5")]
        PreBookingConfirmation = 5,
        [EnumMember(Value = "6")]
        BookingStatus = 6
    }

    class Program
    {
        static void Main(string[] args)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(Request));

            // Create Request object
            Request req = new Request();
            req.request = RequestType.Confirmation;

            // Serialize to File
            using (FileStream fileStream = new FileStream("request.txt", FileMode.Create))
            {
                serializer.WriteObject(fileStream, req);
            }

            // Reset for testing
            req = null;

            // Deserialize from File
            using (FileStream fileStream = new FileStream("request.txt", FileMode.Open))
            {
                req = serializer.ReadObject(fileStream) as Request;
            }

            // Writes True
            Console.WriteLine(req.request == RequestType.Confirmation);
        }
    }
}

После вызова WriteObject содержимое request.txt выглядит следующим образом:

<Request xmlns="petermcg.wordpress.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <request>2</request>
</Request>

Вам понадобится ссылка на сборку System.Runtime.Serialization.dll для DataContractSerializer.

Ответ 4

using System.Xml.Serialization;

public class Request
{    
    [XmlIgnore()]
    public RequestType request;

    public int RequestTypeValue
    {
      get 
      {
        return (int)request;
      } 
      set
      {
        request=(RequestType)value; 
      }
    }
}

public enum RequestType
{
    Booking = 1,
    Confirmation = 2,
    PreBooking = 4,
    PreBookingConfirmation = 5,
    BookingStatus = 6
}

Этот подход работал у меня.

Ответ 5

Поскольку вы назначаете явные непоследовательные значения параметрам перечисления, я предполагаю, что вы хотите указать более одного значения за раз (двоичные флаги), тогда принятый ответ является вашим единственным вариантом. Прохождение в PreBooking | PreBookingConfirmation будет иметь целочисленное значение 9, и сериализатор не сможет десериализовать его, но его использование с помощью прокладки будет работать хорошо. Или, может быть, вы просто пропустили значение 3:)

Ответ 6

Взгляните на класс System.Enum. Метод Parse преобразует представление строки или int в объект Enum, а метод ToString преобразует объект Enum в строку, которая может быть сериализована.