我正在尝试使WCF支持未命名枚举。 我创建了一个代理,当它是枚举类型时可以正常工作。 但是,当它是可空枚举类型时,在反序列化时会失败。 这是我的代理,它是从article修改而来的,我的代码不同之处在于我不想提供已知类型:
当枚举类型不可为空时,一切反序列化正常。
当枚举类型可为空并且有值时,WCF将无法将int反序列化为枚举类型。
编辑:
我认为这可能与WCF如何从代理中处理反序列化有关。以下是我注意到的一些行为,可能会有所帮助。
这是DataContract Surrogates的MSDN。
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));
}
当枚举类型不可为空时,一切反序列化正常。
当枚举类型可为空并且有值时,WCF将无法将int反序列化为枚举类型。
编辑:
我认为这可能与WCF如何从代理中处理反序列化有关。以下是我注意到的一些行为,可能会有所帮助。
- 调用
GetDeserializedObject
时,object obj
将被填充为已经反序列化的对象。例如,看起来WCF反序列化在代理之前启动。 - 使用基础类型调用时,实际上永远不会触发
GetDeserializedObject
,我认为这是因为代理反序列化仅适用于对象。 - WCF无法将枚举类型序列化为值,但它可以很好地从值反序列化。
这是DataContract Surrogates的MSDN。
如何使可空(和非可空)枚举类型严格地从值进行序列化和反序列化?
GetDeserializedObject
方法。如果此过程失败,该方法将不会被调用。如果要在反序列化之前拦截它,则唯一的方法是修改GetDataContractType
方法。我不确定,但如果枚举合同传递到该方法中,您可能可以拦截它们的反序列化方式。 - Eldar