WCF按值枚举代理以支持动态枚举 [英] WCF Enum By Value Surrogates to support dynamic enums

查看:89
本文介绍了WCF按值枚举代理以支持动态枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使WCF支持成为未命名的枚举.我创建了一个代理,可以在枚举时正常工作.但是,当它是可为空的枚举时,它将在反序列化时失败.这是我的替代产品,它是从文章,我的代码有所不同,因为我不想提供已知的类型:

I'm trying to make WCF Support unnamed enums. I've created a Surrogate which works fine when its an enum. However when it's a nullable enum it fails on deserialization. This is my surrogate which was modified from this article, my code differs since I don't want to supply known types:

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.

When the Enum is not nullable everything deserialized fine.
When the Enum is nullable, with a value, WCF will not deserialize the int to Enum.

我认为这可能与WCF如何处理代理人的反序列化有关.这是我注意到的一些行为,可能会有所帮助.

I think this may be related to how WCF handles Deserialization from Surrogates. Here's a few behaviors I've noticed that might be helpful.

  1. 在调用 GetDeserializedObject 时, object obj 将填充一个已经反序列化的对象.例如,在替代之前WCF反序列化似乎已经开始

  1. When calling GetDeserializedObject the object obj will be populated with an object that has already been deserialized. e.g it looks like WCF deserialization kicks in before the surrogate does

当使用基础类型的调用 GetDeserializedObject 实际上从未被点击时,我认为这是因为代理反序列化仅适用于对象

When calling with an the with the underlying type the GetDeserializedObject is actually never hit, I think this is because surrogate Deserialization only works on objects

WCF无法将枚举序列化为该值,但是可以很好地处理从该值进行反序列化的过程.

WCF Cannot Serialize Enums to the value but it handles deserializing from the value just fine.

资源:

这是MSDN 用于数据合同代理

如何获取可为空(和不可为空)的Enum严格从值进行序列化和反序列化?

How can I get nullable (and non-nullable) Enums to serialize and deserialize strictly from values?

推荐答案

下面的行不让您处理 Nullable< Enum> 类型:

Below line not let you handle Nullable<Enum> types :

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

您还需要显式检查 Nullable<> 类型.如下所示:

You also need to check Nullable<> type explicitly. Like below :

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

小提琴进行演示.

这篇关于WCF按值枚举代理以支持动态枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆