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

F#如何将对象序列化为JSON:排除默认值且保留枚举名称

方案1:修复现有DataContractJsonSerializer实现(改造成本最低)

你之前的代码存在两个明显问题:一是实例化的DataContractJsonSerializerSettings完全没有使用,二是没有开启枚举序列化为字符串的配置。调整后的代码如下:

let json<'t> (myObj:'t) =   
    use ms = new MemoryStream() 
    let settings = DataContractJsonSerializerSettings(
        // 开启枚举转字符串输出
        SerializeEnumsAsStrings = true,
        // 不输出默认值的属性,满足未赋值属性忽略的要求
        EmitDefaultValues = false
    )
    let serialiser = DataContractJsonSerializer(typeof<'t>, settings)
    serialiser.WriteObject(ms, myObj)
    // 注意这里建议用UTF8而非Default编码,避免不同环境编码不一致导致乱码
    Encoding.UTF8.GetString(ms.ToArray())

这个方案不需要调整模型代码,也不需要处理额外的类型转换问题,直接可以满足你的三个需求。


方案2:解决System.Text.Json的类型转换报错

这个报错的根本原因是Open API Generator生成的模型中,可空枚举的私有字段_typeCode默认被初始化为0(对应枚举的底层int类型默认值),而非可空值类型的默认值null。而你的枚举定义大概率没有值为0的成员,导致枚举转换器尝试转换不存在的枚举值时抛出类型转换错误。
有两种修复方式:

方式A:自定义可空枚举转换器处理非法值

先实现一个通用的可空枚举转换器,遇到未定义的枚举值时直接输出null,配合忽略null值的配置即可自动跳过未赋值的属性:

public class CustomNullableEnumConverter<TEnum> : JsonConverter<TEnum?> where TEnum : struct, Enum
{
    public override TEnum? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException();

    public override void Write(Utf8JsonWriter writer, TEnum? value, JsonSerializerOptions options)
    {
        if (!value.HasValue || !Enum.IsDefined(value.Value.GetType(), value.Value))
        {
            writer.WriteNullValue();
            return;
        }
        writer.WriteStringValue(Enum.GetName(value.Value.GetType(), value.Value));
    }
}

然后在序列化配置中注册转换器即可:

let options = JsonSerializerOptions()
// 改为忽略null值,非法枚举值会被转换器输出为null后自动跳过
options.DefaultIgnoreCondition <- JsonIgnoreCondition.WhenWritingNull
// 注册你的自定义可空枚举转换器
options.Converters.Add(CustomNullableEnumConverter<ExpressPackageReference.TypeCodeEnum>())
// 其他普通枚举仍用默认的字符串转换器
options.Converters.Add(JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
let jsonString:string = JsonSerializer.Serialize(shipmentRequest, options)

方式B:调整Open API Generator生成配置

在生成模型的命令中添加参数,让生成器自动给所有可空枚举属性设置默认值为null,并且添加忽略默认值的序列化特性,从根源避免非法值的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:42:01