Я пытаюсь сделать поддержку WCF безымянным перечислением. Я создал суррогат, который отлично работает, когда его перечисление. Однако, когда это nullable перечисление, оно терпит неудачу при десериализации. Это мой суррогат, который был изменен из этой статьи , мой код отличается, так как я не хочу предоставлять известные типы:
public class EnumValueDataContractSurrogate : IDataContractSurrogate
{
#region Interface Implementation
public Type GetDataContractType(Type type)
{
return type;
}
public object GetObjectToSerialize(object obj, Type targetType)
{
if (null == obj)
{
return obj;
}
if (targetType.IsEnum)
{
return EnumExtensions.ChangeToUnderlyingType(targetType, obj);
}
if (targetType.IsNullable() && targetType.GetUnderlyingType().IsEnum)
{
return (int?)obj;
}
return obj;
}
// This Method is never invoked for targetType enum/enum?
// However all the other parameters work fine
public object GetDeserializedObject(object obj, Type targetType)
{
if (targetType.IsNullable())
{
targetType = targetType.GetUnderlyingType();
}
if ((false == targetType.IsEnum) || (null == obj))
{
return obj;
}
var stringObj = obj as string;
if (null != stringObj)
{
return Enum.Parse(targetType, stringObj);
}
return Enum.ToObject(targetType, obj);
}
public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
{
//not used
return;
}
public object GetCustomDataToExport(Type clrType, Type dataContractType)
{
//Not used
return null;
}
public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
{
//not used
return null;
}
public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
{
//not used
return null;
}
public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
{
//not used
return typeDeclaration;
}
#endregion
}
public static object ChangeToUnderlyingType(Type enumType, object value)
{
return Convert.ChangeType(value, Enum.GetUnderlyingType(enumType));
}
Когда Enum не обнуляется, все десериализовано нормально.
Когда Enum обнуляется, со значением, WCF не будет десериализовать int в Enum.
EDIT:
Я думаю, это может быть связано с тем, как WCF занимается десериализацией суррогатов. Вот несколько вариантов поведения, которые я заметил и которые могут быть полезны.
При вызове GetDeserializedObject
object obj
будет заполнен объектом, который уже был десериализован. например, похоже, что десериализация WCF начинается раньше, чем суррогат делает
Когда при вызове с базовым типом GetDeserializedObject
фактически никогда не срабатывает, я думаю, это потому, что только суррогатная десериализация работает с объектами
WCF не может сериализовать перечисления в значение, но отлично обрабатывает десериализацию из значения.
Ресурсы:
Это MSDN для суррогатов обработки данных
Как я могу получить обнуляемые (и не обнуляемые) перечисления для сериализации и десериализации строго из значений?