You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用.NET Framework的WCF将自定义类序列化为JSON原始类型?

解决方案

方案一:用IDataContractSurrogate扩展DataContractJsonSerializer

这是适配你现有WCF序列化场景的最优方案,无需修改原有类结构,一次定义即可全局复用转换逻辑,彻底解决多处使用时的冗余问题。

1. 实现自定义代理类

创建一个实现IDataContractSurrogate的类,接管目标类型的序列化/反序列化转换逻辑:

public class CustomTypeSurrogate : IDataContractSurrogate
{
    // 指定序列化时自定义类型对应的原始替换类型
    public Type GetDataContractType(Type type)
    {
        if (type == typeof(Joiner))
            return typeof(string);
        if (type == typeof(SingleIntClass))
            return typeof(int);
        return type;
    }

    // 序列化阶段:将自定义对象转换为原始类型值
    public object GetObjectToSerialize(object obj, Type targetType)
    {
        if (obj is Joiner joiner)
            return joiner.ToString(); // 复用类已定义的标准字符串表示
        if (obj is SingleIntClass intObj)
            return intObj.IntValue; // 直接返回整数成员的值
        return obj;
    }

    // 反序列化阶段:将原始类型值转换回自定义对象
    public object GetDeserializedObject(object obj, Type targetType)
    {
        if (targetType == typeof(Joiner) && obj is string str)
            return Joiner.Parse(str); // 假设Joiner类有静态Parse方法用于重建对象
        if (targetType == typeof(SingleIntClass) && obj is int num)
            return new SingleIntClass { IntValue = num };
        return obj;
    }

    // 以下接口方法无需自定义逻辑,返回默认值即可
    public object GetCustomDataToExport(Type clrType, Type dataContractType) => null;
    public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType) => null;
    public void GetKnownCustomDataTypes(Collection<Type> customDataTypes) { }
    public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData) => null;
    public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit) => typeDeclaration;
}

2. 配置序列化器使用代理

初始化DataContractJsonSerializer时传入代理实例,后续所有序列化/反序列化操作都会自动应用转换规则:

var serializerSettings = new DataContractJsonSerializerSettings
{
    DataContractSurrogate = new CustomTypeSurrogate(),
    UseSimpleDictionaryFormat = true
};

// 序列化示例:Joiner数组会被转换为字符串数组
var joinerList = new List<Joiner> 
{ 
    new Joiner { A = "foo", B = "bar" }, 
    new Joiner { A = "hello", B = "world" } 
};

using (var stream = new MemoryStream())
{
    var serializer = new DataContractJsonSerializer(typeof(List<Joiner>), serializerSettings);
    serializer.WriteObject(stream, joinerList);
    stream.Position = 0;
    var jsonResult = new StreamReader(stream).ReadToEnd();
    // 输出结果类似 ["foo,bar", "hello,world"],而非嵌套对象数组
}

// 反序列化示例
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonResult)))
{
    var serializer = new DataContractJsonSerializer(typeof(List<Joiner>), serializerSettings);
    var deserializedList = (List<Joiner>)serializer.ReadObject(stream);
}

方案二:用.NET Framework 4.8自带的System.Text.Json

如果你的环境允许使用System.Text.Json(.NET Framework 4.8可通过NuGet安装,部分Windows 10版本也自带),可以通过自定义转换器实现更简洁的逻辑:

1. 编写类型转换器

public class JoinerConverter : JsonConverter<Joiner>
{
    public override Joiner Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return Joiner.Parse(reader.GetString());
    }

    public override void Write(Utf8JsonWriter writer, Joiner value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}

public class SingleIntClassConverter : JsonConverter<SingleIntClass>
{
    public override SingleIntClass Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return new SingleIntClass { IntValue = reader.GetInt32() };
    }

    public override void Write(Utf8JsonWriter writer, SingleIntClass value, JsonSerializerOptions options)
    {
        writer.WriteNumberValue(value.IntValue);
    }
}

2. 配置并使用序列化器

var jsonOptions = new JsonSerializerOptions();
jsonOptions.Converters.Add(new JoinerConverter());
jsonOptions.Converters.Add(new SingleIntClassConverter());

// 序列化
var json = JsonSerializer.Serialize(joinerList, jsonOptions);
// 反序列化
var deserialized = JsonSerializer.Deserialize<List<Joiner>>(json, jsonOptions);

关键注意点

  • 确保Joiner类有可靠的ToString()(序列化用)和静态Parse()(反序列化用)方法;SingleIntClass要保证整数成员的访问权限正常。
  • 方案一完全基于WCF自带类,无额外依赖,适合环境受限的场景;方案二更简洁,但需确认环境支持System.Text.Json。

内容的提问来源于stack exchange,提问作者bchase

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 17:53:25