Невозможно произвести перечисление из кода c# в строку json - PullRequest
0 голосов
/ 24 января 2020

Я использую JsonForm для создания динамических c форм в моем базовом веб-приложении MVC. Я использую System.Text.Json.JsonSerializer.Serialize в следующем коде в моей модели представления для создания простой формы с одним полем. Моя цель - в конечном итоге сохранить это json в базе данных и извлечь его оттуда.

 public TestsViewModel GetFormControls1()
        {
            var myJsonModel = new
            {
                schema = new
                {
                    client = new
                    {
                        type = "object",
                        title = "Client",
                        properties = new
                        {
                            forename = new
                            {
                                type = "string",
                                title = "Forename",
                                minLength = 3,
                                maxLength = 10,
                            }
                        }
                    }
                },
                form = new List<Object>
                {
                    new {
                        key = "client.forename",
                        title = "Forename"
                    }
                },
                value = new
                {
                    client = new
                    {
                        forename = "",
                    }
                }
            };

            TestsViewModel homeVm = new TestsViewModel();
            homeVm.FormControls = System.Text.Json.JsonSerializer.Serialize(myJsonModel);
            return homeVm;
        }

Приведенный выше код работает нормально и создает следующую схему json, которая затем используется для создания формы.

{
  "schema": {
    "client": {
      "type": "object",
      "title": "Client",
      "properties": {
        "forename": {
          "type": "string",
          "title": "Forename",
          "minLength": 3,
          "maxLength": 10
        }
      }
    }
  },
  "form": [
    {
      "key": "client.forename",
      "title": "Forename"
    }
  ],
  "value": {
    "client": {
      "forename": ""
    }
  }
}

Теперь мне нужно создать перечисление для моего json, чтобы в форме мог появиться выпадающий список для выбора пола. Однако я не могу сделать это с помощью кода c#. Может кто-нибудь помочь? Я хотел бы, чтобы мой код c# выдал следующий json (обратите внимание на две записи для пола в схеме и форме).

{
  "schema": {
    "client": {
      "type": "object",
      "title": "Client",
      "properties": {
        "forename": {
          "type": "string",
          "title": "Forename",
          "minLength": 3,
          "maxLength": 10
        },
        "gender": {
          "type": "string",
          "title": "Gender",
          "enum": [
            "male",
            "female",
            "alien"
          ]
        }
      }
    }
  },
  "form": [
    {
      "key": "client.forename",
      "title": "Forename"
    },
    {
      "key": "client.gender",
      "titleMap": {
        "male": "Dude",
        "female": "Dudette",
        "alien": "I'm from outer space!"
      }
    }
  ],
  "value": {
    "client": {
      "forename": ""
    }
  }
}

Я пытался использовать следующий код, но enum - ключевое слово в c#, поэтому я получаю сообщение об ошибке.

gender = new
                            {
                                type = "string",
                                title = "Gender",
                                enum = "[male, female, alien]"
                            }

Также Enum = "[male, female, alien]" производит "Enum": "[male, female, alien]" вместо "enum": [ "male", "female", "alien" ]

У меня есть таблица поиска пола, которую я в конечном итоге буду использовать, чтобы произвести выше enum каким-то образом, поэтому любая идея относительно этого также будет полезна. Комментарий

UPDATE @ db c решает большую часть моей проблемы. Тем не менее, я все еще борюсь с производством titleMap json, если я пытаюсь отобразить строку в int.

var gender3 = new
            {
                type = "string",
                title = "Gender",
                titleMap = new List<string> { new string("1" + ":" + "Male"), new string("2" + ":" + "Female")}
            };

Выше кода выдает

{
  "type": "string",
  "title": "Gender",
  "titleMap": [
    "1:Male",
    "2:Female"
  ]
}

Однако мне нужны и 1, и Мужчины в своих двойных кавычках внутри {} вместо [], как показано ниже.

{
  "type": "string",
  "title": "Gender",
  "titleMap": {
    "1": "Male",
    "2": "Female"
  }
}

Ответы [ 2 ]

1 голос
/ 25 января 2020

enum - ключевое слово в C#, поэтому вам нужно добавить @ к перечислению

gender = new
                            {
                                type = "string",
                                title = "Gender",
                                @enum = new string[3]{"male", "female", "alien"}
                            }
1 голос
/ 25 января 2020

Насколько я понимаю, вы пытаетесь сериализовать массив значений enum в виде их текстовых имен в JSON. Самое простое решение для этого - добавить массив или список свойств перечислений в ваш TestViewModel и использовать конвертер JsonStringEnumConverter для их сериализации в виде строк, а не чисел.

Вот пример того, как вы можете достичь того, что ищете.

Допустим, у вас есть некоторое перечисление с набором значений:

//This is an arbitrary enum, this could be 'Gender', in your case
public enum TestEnum
{
    value1,
    value2,
    value3,
    value4,
}

И вы хотите записать массив этих перечислений ценности. Добавьте список свойств перечислений (или массив перечислений) в вашу модель. Если вы хотите, чтобы имя свойства в JSON было одним из зарезервированных слов (например, enum), либо переопределите имя, используя атрибут JsonPropertyName (и сохраняйте имя в любом программном ключе ):

public class TestsViewModel_Option1
{
    // In your case, this property could be called 'Genders' to be self-documenting
    [JsonPropertyName("enum")]
    public List<TestEnum> ListOfEnums { get; set; }
}

ИЛИ, используйте символ @, если вы действительно хотите, чтобы имя свойства было зарезервированным ключевым словом и не хотите / не можете использовать атрибут по какой-то причине.

public class TestsViewModel_Option2
{
    // Or use fixed-size array, TestEnum[], if needed
    public List<TestEnum> @enum { get; set; }
}

И вот как выглядит ваш код с JsonSerializer:

private static void SerializeListOfEnums()
{
    var model1 = new TestsViewModel_Option1
    {
        ListOfEnums = { TestEnum.value1, TestEnum.value3 }
    };

    var options = new JsonSerializerOptions
    {
        Converters = { new JsonStringEnumConverter() }
    };

    // {"enum":["value1","value3"]}
    Console.WriteLine(JsonSerializer.Serialize(model1, options));

    var model2 = new TestsViewModel_Option2
    {
        @enum = { TestEnum.value1, TestEnum.value3 }
    };

    // {"enum":["value1","value3"]}
    Console.WriteLine(JsonSerializer.Serialize(model2, options));
}
...