Сериализация Дискриминационного Союза в F # с использованием FSharpLu - Как скрыть имя свойства от Дискриминационных Типов Союза? - PullRequest
0 голосов
/ 08 декабря 2018

Я новичок в F #, и у меня есть задача сериализовать Дискриминационный Союз.Это само по себе просто, вы можете сериализовать его, и вы получите хороший (безобразный) случай: fields: набор узлов.

Используя Compact Serializer от FSharpLu (https://github.com/Microsoft/fsharplu) мы можемпереведите это в более управляемый формат, без Case: Field: узлов. Однако вместо этого мы получаем имя Типа, который был сериализован как имя узла. Это не требуется.

Если у меня естьтакие типы, как:

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 и изменил компактный сериализатор, чтобы больше не записывать начало объектов и конец объектов в дискриминированном союзе. Это позволяет получить результат, который я ищудля. Однако я не знаю сейчас, как я могу чертитьЧувствую, что в моей работе ... Является ли раздвоенное репо слишком большим, чтобы его поддерживать, стоит ли оно этого крошечного изменения?Хм ...

Изменения произошли с Строка 146 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)

1 Ответ

0 голосов
/ 10 декабря 2018

Вот несколько альтернатив, которые вы можете рассмотреть, если не хотите писать / поддерживать пользовательский конвертер Json.NET:

1.Используйте некоторую другую библиотеку сериализации

Два варианта, которые дают вам больше контроля над сериализацией данных:

  1. Thoth.Json.Net
  2. Хирон

2.Используйте объекты передачи данных, которые сериализуются, как вы хотите

    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)

3.Развернуть и коробка

    let objData =
        data
        |> Array.map (fun entryOrGroup ->
            match entryOrGroup with
            | Entry entry -> box entry
            | Group group -> box group)


    JsonConvert.SerializeObject(objData, Formatting.Indented)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...