Home > Back-end >  System.Text.Json.JsonException: The JSON value could not be converted to Entities.UserCard. Path: $[
System.Text.Json.JsonException: The JSON value could not be converted to Entities.UserCard. Path: $[

Time:04-08

This is my program class where the migration is going to start

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.SeedUsers(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>();
            });
}

This is my main class

public class AppUser
{
    public int Id { get; set; }
    [StringLength(20)]

    public string UserName { get; set; }

    public byte[] PasswordHash { get; set; }

    public byte[] PasswordSalt { get; set; }

    public DateTime DateOfBirth { get; set; }

    public DateTime Created { get; set; }=DateTime.Now;

    public DateTime LastActive { get; set; }=DateTime.Now;

    public string Gender { get; set; }
    public string City { get; set; }
    public string Country { get; set; }

    public ICollection<Photo> Photos { get; set; }

    public UserCard Cards { get; set; }

    public int GetAge(){
        return DateOfBirth.CalculateAge();
    }
}

And this is the UserCard that i want to be linked with AppUser in the DataBase

[Table("Cards")]
public class UserCard
{
     public int Id { get; set; }
    public string Code { get; set; }
    public string Status { get; set; }
    public string Type { get; set; }

    public AppUser AppUser{ get; set; }
    public int AppUserId { get; set; }
}

Here is how my seed function is looking

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

        var userData=await System.IO.File.ReadAllTextAsync("Data/UserSeedData.json");
        var users=JsonSerializer.Deserialize<List<AppUser>>(userData);
        foreach (var user in users)
        {
            using var hmac=new HMACSHA512();
            user.UserName = user.UserName.ToLower();
            user.PasswordHash=hmac.ComputeHash(Encoding.UTF8.GetBytes("admin"));
            user.PasswordSalt=hmac.Key;
            context.Users.Add(user);
        }

        await context.SaveChangesAsync();
    }

And this is the data that i want to put in the database.Here i have another class Photos that is why it is there

[
{
    "UserName": "Tami",
    "Gender": "female",
    "DateOfBirth": "1995-09-28",
    "Created": "2020-05-01",
    "LastActive": "2020-05-29",
    "City": "Haring",
    "Country": "San Marino",
    "Photos": [
        {
            "Url": "https://randomuser.me/api/portraits/women/94.jpg",
            "IsMain": true
        }
    ],
    "Cards": [
        {
            "Code": "123123543",
            "Status": "notActive",
            "Type": "default"
        }
    ]
}
]

When I enter: dotnet watch run my database is going to create the tables correctly with the right linking but when the seed is happening I get this error

  fail: API.Program[0]
  An error occurred during migration
  System.Text.Json.JsonException: The JSON value could not be converted to Entities.UserCard. Path: $[0].Cards | LineNumber: 15 | BytePositionInLine: 18.
     at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
     at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
     at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
     at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
     at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
     at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
     at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
     at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
     at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
     at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo jsonTypeInfo, Nullable`1 actualByteCount)
     at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo jsonTypeInfo)
     at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
     at API.Data.Seed.SeedUsers(DataContext context) in C:\Users\Alejandro\Desktop\ProjectApp\API\Data\Seed.cs:line 19
     at API.Program.Main(String[] args) in C:\Users\Alejandro\Desktop\ProjectApp\API\Program.cs:line 24

I found the problem

  public ICollection<Photo> Photos { get; set; }
    public UserCard Cards { get; set; }

I just needed to put ICollection to the Cards prop but I need help to solve this .Now with ICollection the relation is one to many but for cards I want the relation to be 1 to 1 what do I need to do in this case?

CodePudding user response:

For 1 to 1 relation, you may change the json structure like this;

[
{
    ...
    "Cards": {
            "Code": "123123543",
            "Status": "notActive",
            "Type": "default"
        }
    ...

}
]

Notice that Cards property is now an object, rather than an array.

  • Related