gpt4 book ai didi

c# - WCF 枚举按值代理支持动态枚举

转载 作者:行者123 更新时间:2023-12-03 05:18:22 26 4
gpt4 key购买 nike

我正在尝试让 WCF 支持未命名枚举。我创建了一个代理,当它是枚举时它工作得很好。但是,当它是可为 null 的枚举时,它会在反序列化时失败。这是我的代理,是从 article 修改而来的,我的代码有所不同,因为我不想提供已知类型:

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 可为空且有值时,WCF 不会将 int 反序列化为 Enum。

编辑:

我认为这可能与 WCF 如何处理来自代理的反序列化有关。以下是我注意到的一些可能有用的行为。

  1. 调用GetDeserializedObject时,object obj将使用已反序列化的对象填充。例如,看起来 WCF 反序列化在代理执行之前就开始了

  2. 当使用底层类型调用时,GetDeserializedObject实际上从未被命中,我认为这是因为代理反序列化仅适用于对象

  3. WCF 无法将枚举序列化为值,但它可以很好地处理值的反序列化。

资源:

这是MSDN对于数据合约代理

如何获取可空(和不可空)枚举以严格从值进行序列化和反序列化?

最佳答案

下面这行不让你处理Nullable<Enum>类型:

  if ((false == targetType.IsEnum) || (null == obj))
{
return obj;
}

您还需要检查Nullable<>明确键入。如下所示:

if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
targetType = targetType.GetGenericArguments()[0];
}

Fiddle这证明了这一点。

关于c# - WCF 枚举按值代理支持动态枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59619094/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com