System.Text.Json.Исключение JSONException: не удается преобразовать Json в DataModel

#c# #json #serialization #seed #system.text.json

#c# #json #сериализация #начальное значение #system.text.json

Вопрос:

Я пытаюсь ввести данные в базу данных из файла json, но продолжаю сталкиваться с той же ошибкой. Как показано ниже в трассировке стека. У меня есть класс AppQuestion и класс IncorrectAnswer. Данные должны соответствовать этим моделям и передаваться в мою базу данных. При попытке десериализации кажется, что ошибка вызвана неправильным начальным массивом. Я бы предпочел использовать System.Text.Json вместо Newsoft. Есть ли способ обработать данные и оставаться верным моим моделям.

SeedData.json

 [
  {
    "Question": "Question1",
    "Incorrect": ["Answer1", "Answer2", "Answer3"],
    "Correct": "Answer4"
  }, {
    "Question": "Question2",
    "Incorrect": ["Answer1", "Answer2", "Answer4"],
    "Correct": "Answer3"
  }
]
  

C # Код

 public class Seed
{
    public static async Task SeedQuestions(DataContext context)
    {
        if (await context.Questions.AnyAsync()) return;

        var questionData = await System.IO.File.ReadAllTextAsync("Data/QuestionSeedData.json");

        var questions = JsonSerializer.Deserialize<List<AppQuestion>>(questionData);
        foreach(var question in questions)
        {
            context.Questions.Add(question);
        }

        await context.SaveChangesAsync();
    }
}

public class AppQuestion
{
    
    public int Id { get; set; }
    public string Question { get; set; }
    public ICollection<IncorrectAnswer> Incorrect { get; set; }
    public string Correct { get; set; }
}


public class IncorrectAnswer
{
    public int Id { get; set; }

    public string Incorrect { get; set; }
    public AppQuestion AppQuestion { get; set; }

    public int AppQuestionId { get; set; }
}


public class DataContext : DbContext
{
    public DataContext( DbContextOptions options) : base(options)
    {
    }
    public DbSet<AppQuestion> Questions {get; set;}

    public DbSet<AppUser> Users { get; set; }
}
public class Program
{
    public static async Task Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
        using var scope = host.Services.CreateScope();
        var services = scope.ServiceProvider;
        try
        {
            var context = services.GetRequiredService<DataContext>();
            await context.Database.MigrateAsync();
            await Seed.SeedQuestions(context);
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred during migration");
        }
        await host.RunAsync();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}
  

Трассировка стека

 fail: API.Program[0]
  An error occurred during migration
  System.Text.Json.JsonException: The JSON value could not be converted to API.Entities.IncorrectAnswer. Path: $[0].Incorrect[0] | LineNumber: 3 | BytePositionInLine: 28.
     at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
     at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReaderamp; reader, Type typeToConvert, JsonSerializerOptions options, ReadStackamp; state, Tamp; value)
     at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReaderamp; reader, Type typeToConvert, JsonSerializerOptions options, ReadStackamp; state, Tamp; value)
     at System.Text.Json.Serialization.Converters.IEnumerableDefaultConverter`2.OnTryRead(Utf8JsonReaderamp; reader, Type typeToConvert, JsonSerializerOptions options, ReadStackamp; state, TCollectionamp; value)
     at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReaderamp; reader, Type typeToConvert, JsonSerializerOptions options, ReadStackamp; state, Tamp; value)
     at System.Text.Json.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStackamp; state, Utf8JsonReaderamp; reader)
     at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReaderamp; reader, Type typeToConvert, JsonSerializerOptions options, ReadStackamp; state, Tamp; value)
     at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReaderamp; reader, Type typeToConvert, JsonSerializerOptions options, ReadStackamp; state, Tamp; value)
     at System.Text.Json.Serialization.Converters.IEnumerableDefaultConverter`2.OnTryRead(Utf8JsonReaderamp; reader, Type typeToConvert, JsonSerializerOptions options, ReadStackamp; state, TCollectionamp; value)
     at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReaderamp; reader, Type typeToConvert, JsonSerializerOptions options, ReadStackamp; state, Tamp; value)
     at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReaderamp; reader, JsonSerializerOptions options, ReadStackamp; state)
     at System.Text.Json.JsonSerializer.ReadCore[TValue](JsonConverter jsonConverter, Utf8JsonReaderamp; reader, JsonSerializerOptions options, ReadStackamp; state)
     at System.Text.Json.JsonSerializer.ReadCore[TValue](Utf8JsonReaderamp; reader, Type returnType, JsonSerializerOptions options)
     at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, Type returnType, JsonSerializerOptions options)
     at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
     at API.Data.Seed.SeedQuestions(DataContext context) in C:UsersfahuaDocumentsTriviaTandemAPIDataSeed.cs:line 20
     at API.Program.Main(String[] args) in C:UsersfahuaDocumentsTriviaTandemAPIProgram.cs:line 26
  

Комментарии:

1. Не используйте изображения, добавьте код.

2. Обновлено. Спасибо.

3. Почему у вас есть пробелы после "Question " токена in? Предназначено ли это?

4. Нет, не предназначено, похоже, это не вызвало проблемы из-за этого. Отредактировал его без пробела. Проблема по-прежнему сохраняется.

Ответ №1:

Incorrect свойство в AppQuestion классе — это набор IncorrectAnswer объектов, но в вашем json incorrect — массив строк.

Вам нужно либо изменить свою модель, либо json.

Ответ №2:

В конце концов, я нашел страницу, на которой явно упоминается элемент данных в атрибутах. Я думаю, что заполнение данных должно иметь более чистый результат, но пока это работает.

 public class Example
{
    [DataMember(Name="Question")]
    public string Question  { get; set; }

    [DataMember(Name="Incorrect")]
    public IList<string> Incorrect { get; set; }

    [DataMember(Name="Correct")]
    public string Correct { get; set; }
}


public class Seed
{
    public Seed()
    {
    }

    public static async Task SeedQuestions(DataContext context)
    {
        if (await context.Questions.AnyAsync()) return;

        var questionData = await System.IO.File.ReadAllTextAsync("Data/QuestionSeedData.json");

        var myDeserializedClass = JsonSerializer.Deserialize<List<Example>>(questionData);
        

        foreach (var item in myDeserializedClass)
        {
            var appQuestion = new AppQuestion();
            var incorrectAnswerList = new List<IncorrectAnswer>();

            appQuestion.Question = item.Question;
            appQuestion.Correct = item.Correct;
            foreach (var thing in item.Incorrect)
            {
                var incorrectAnswer = new IncorrectAnswer();
                incorrectAnswer.Incorrect = thing;
                incorrectAnswerList.Add(incorrectAnswer);
            }
            appQuestion.Incorrect = incorrectAnswerList;

            context.Questions.Add(appQuestion);
        }
        await context.SaveChangesAsync();
    }
}