我是F#的新手,有一个任务来序列化受歧视联盟。这本身很简单,您可以对其进行序列化,然后得到一个很好的(丑陋的)情况:fields:节点集。
使用FSharpLu(https://github.com/Microsoft/fsharplu)的紧凑型序列化程序,我们可以将此格式简化为更易于管理的格式,而无需使用Case:Field:节点。 但是,相反,我们获得了被序列化为节点名称的Type的名称。这是不需要的。
如果我有以下类型:
type Entry = {
id: string
foo: int
bar: string
}
type Group = {
id: string
entryList: Entry seq
}
type EntryOrGroup =
| Entry of Entry
| Group of Group
在输出中,是一个EntryOrGroup数组,我将使每个节点都用其类型名修饰,这是我不想要的。
是否可以隐藏类型名称?但仍然输出所需的json节点?
编辑: 当前输出示例:
[
{
Group: {
id: "firstEntry",
entryList: [
{
id: "foobar",
foo: 12,
bar: "something"
},
{
id: "barfoo",
foo: 13,
bar: "somethingElse"
}
]
},
{
Entry: {
id: "foofoobar",
foo: 16,
bar: "notSomething"
}
}
}
]
所需输出示例:
[
{
{
id: "firstEntry",
entryList: [
{
id: "foobar",
foo: 12,
bar: "something"
},
{
id: "barfoo",
foo: 13,
bar: "somethingElse"
}
]
},
{
{
id: "foofoobar",
foo: 16,
bar: "notSomething"
}
}
}
]
Edit2: 我分叉了FSharpLu存储库,并更改了Compact Serializer,使其不再在Discriminated Union中写入对象的开头和对象的结尾。这样可以达到我想要的结果。但是,我现在不知道我该如何在工作中实现它……分叉的仓库是否需要维护太多,对于这个微小的变化值得吗?嗯...
更改来自Line 146 of Compact.fs: 发件人:
else
let case, fields = getUnionFields value
match fields with
// Field-less union case
| [||] -> writer.WriteValue(convertName case.Name)
// Case with single field
| [|onefield|] ->
writer.WriteStartObject()
writer.WritePropertyName(convertName case.Name)
serializer.Serialize(writer, onefield)
writer.WriteEndObject()
// Case with list of fields
| _ ->
writer.WriteStartObject()
writer.WritePropertyName(convertName case.Name)
serializer.Serialize(writer, fields)
writer.WriteEndObject()
收件人:
else
let case, fields = getUnionFields value
match fields with
// Field-less union case
| [||] -> writer.WriteValue(convertName case.Name)
// Case with single field
| [|onefield|] ->
serializer.Serialize(writer, onefield)
// Case with list of fields
| _ ->
writer.WritePropertyName(convertName case.Name)
serializer.Serialize(writer, fields)
答案 0 :(得分:1)
如果您不想编写/维护自定义Json.NET转换器,可以考虑以下几种选择:
1。使用其他一些序列化库
两种选择可让您更好地控制数据的序列化方式:
2。使用根据需要序列化的数据传输对象
:right
3。取消扭曲并装箱
type EntryOrGroupDTO = {
id: string
foo: int option
bar: string option
entryList: Entry seq option
}
let dtoData =
data
|> Array.map (fun entryOrGroup ->
match entryOrGroup with
| Entry entry ->
{ id = entry.id
foo = Some entry.foo
bar = Some entry.bar
entryList = None }
| Group group ->
{ id = group.id
foo = None
bar = None
entryList = Some group.entryList })
let settings =
JsonSerializerSettings(
NullValueHandling=NullValueHandling.Ignore,
Converters=[|CompactUnionJsonConverter()|]
)
JsonConvert.SerializeObject(dtoData, Formatting.Indented, settings)