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

标签 c# wcf enums

我正在尝试让 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/

相关文章:

ajax - 在 WCF 服务上来自 AJAX 的 REST 请求期间在 CORS 中启用 OPTIONS 方法

c# - 如何在 .NET 类库中创建 "abstract"枚举?

string - 在 Rust 中匹配 Option 静态字符串文字

c# - 从 EF for PostGresql 生成的查询中的非最佳计数

c# - 无法从 Docker 中的 ASP.NET Core 3.1 连接到本地 SQL Server

c# - 如何使用 StructureMap 摆脱代码中的 ObjectFactory

c# - 如何确定 Web 服务是否正在运行?

java - 从其参数获取 ENUM 类型

c# - 打开 App 时不显示 PUSH

c# - 在 ASP.NET Core 应用程序中设置 RabbitMQ 消费者