【问题标题】:How to Serialize an Object to Json in F# excluding defaults and Keeping Enum Names如何在 F# 中将对象序列化为 Json,不包括默认值和保留枚举名称
【发布时间】:2021-09-03 06:31:11
【问题描述】:

我认为这很容易,但我在勾选我需要的所有框时遇到问题。

我需要

  • 将对象序列化为 Json
  • 忽略任何未设置的属性
  • 使用 ENum 名称而不是整数值

我已经使用基于 .yaml 规范的开放 API 生成器为此生成了所有模型。

我的第一次尝试是从看起来像旧序列化器的代码中获取一些代码

let json<'t> (myObj:'t) =   
    use ms = new MemoryStream() 
    let serialiser: DataContractJsonSerializer = new DataContractJsonSerializer(typeof<'t>)
    let settings: DataContractJsonSerializerSettings = new DataContractJsonSerializerSettings()
    
    (new DataContractJsonSerializer(typeof<'t>)).WriteObject(ms, myObj) 
    Encoding.Default.GetString(ms.ToArray()) 

这个函数实际上做的一切都很好——除了它复制的是枚举数字而不是名称,我看不到一个选项来实现这一点。

我的另一个尝试是使用 System.Text.Json.JsonSerializer:

    let options 
        = new JsonSerializerOptions(
            )
    options.DefaultIgnoreCondition <- JsonIgnoreCondition.WhenWritingDefault
    options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
    let jsonString:string = JsonSerializer.Serialize(shipmentRequest, options)

我尝试了一些不同的方法(包括排除 Enum 转换器),但总是出现以下错误。

Unable to cast object of type 'System.Int32' to type 
'System.Nullable`1[Zimpla.Model.ExpressPackageReference+TypeCodeEnum]'

遇到问题的具体对象(大致)是:

[DataContract(Name = "ExpressPackageReference")]
public partial class ExpressPackageReference : IEquatable<ExpressPackageReference>, IValidatableObject
{

......etc

        [DataMember(Name = "typeCode", EmitDefaultValue = false)]
    public TypeCodeEnum? typeCode 
    { 
        get{ return _typeCode;}
        set
        {
            _typeCode = value;
            _flagtypeCode = true;
        }
    }

这个特定的属性甚至没有设置,所以理论上应该跳过它。我可能没有正确生成对象

【问题讨论】:

  • 您能否提供一个对象的示例以及序列化后的样子?
  • @AndreasÅgren 谢谢 - 我刚刚更新了文本
  • 您是否考虑过简单地手动进行 [反] 序列化?除非您有一个大的和/或非常不稳定的 API,否则使用现成的序列化程序节省的时间可能少于浪费在学习和配置它的时间。
  • @Guran - 这些代码都是使用 Open API 生成器生成的(它实际上是在使用 DHL API - 他们提供了一个 .yaml 文件用于定义)。所以我不确定我是否理解“现成的序列化程序”的意思。我认为顶部使用 System.Text.Json.JsonSerializer 的代码行已经准备好了。
  • @MartinThompson 抱歉,您的问题有点挑战框架。如果生成的代码给您带来麻烦,那么解决方案可能不是生成代码而是手动编写。 (并不是说代码生成可能不是正确的选择,只是应该是有意识的选择)

标签: f# system.text.json


【解决方案1】:

如果不了解这里的所有细节,我想您是在问如何将对象序列化为 json,同时使用 System.Text.Json 省略所有 null 属性。

为此,您必须设置以下选项:

options.IgnoreNullValues <- true

以下是此选项的文档: https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.ignorenullvalues?view=net-5.0#System_Text_Json_JsonSerializerOptions_IgnoreNullValues

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多