У меня была похожая проблема, когда я хотел, чтобы класс SensorReading , имеющий свойства Enum 'type' и 'unit', сериализовался с именем значений Enum. (Результат по умолчанию равен 0, если Enum не имеет явного числового значения)
До того, как сериализованный результат выглядел так:
[{"id":"0","type":0,"value":"44.00","unit":0}]
Что я хотел, так это:
[{"id":"0","type":"temperature","value":"44.00","unit":"C"}]
В приведенном ниже примере функции я регистрирую пользовательский сериализатор 'EnumConverter <<em> SensorReading >' перед сериализацией объекта.
public static string ToSJSon(object obj)
{
var jss = new JavaScriptSerializer();
jss.RegisterConverters(new[] { new EnumConverter<SensorReading>() });
return jss.Serialize(obj);
}
Вот общий EnumConverter
public class EnumConverter<T> : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get
{
return new[] { typeof(T) };
}
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException(String.Format("'{0}' does not yet implement 'Deserialize", this.GetType().Name));
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
IDictionary<string, object> serialized = new Dictionary<string, object>();
if (obj.GetType() == typeof(T))
{
if (obj.GetType().IsEnum)
{
serialized[obj.GetType().Name] = Enum.GetName(obj.GetType(), obj); ;
}
else
{
var sourceType = obj.GetType();
var properties = sourceType.GetProperties();
foreach (PropertyInfo property in properties)
{
if (property.CanRead)
{
if (property.PropertyType.IsEnum)
{
var str = Enum.GetName(property.PropertyType, property.GetValue(obj, null));
serialized[property.Name] = str;
}
else
{
serialized[property.Name] = property.GetValue(obj, null);
}
}
}
}
}
return serialized;
}
}
Пользовательский сериализатор объявляет, что сериализует объекты типа T, и в Serialize он зацикливает все читаемые свойства. Если свойство является Enum, оно возвращает имя вместо значения в словарь.
Это может быть распространено на другие типы свойств, не сериализующие, как мы хотим.
Я добавил отдельный тест, если в качестве пользовательского сериализатора (ов) T используется Enum. Затем вместо этого выведите имя класса Enum и его значение. Результат будет выглядеть так:
[{"id":"0","type":{"ReadingType":"temperature"},"value":"44.00","unit":{"ReadingUnit":"C"}}]
Это может быть лучше, если вы планируете десериализацию и хотите знать, к какому типу Enum относится значение.