C
C#3mo ago
Al3mid3x

Seeding Data Into Database

Hello there, I'm still new to asp.net and i've been learning through a course on this Course. At episode 83. they were talking about seeding data into database but when i tried to apply the code they used i had an error about the required fields being null the data are random generated in a .json file.
5 Replies
Al3mid3x
Al3mid3x3mo ago
User:
c#
using API.Extensions;

namespace API.Entities
{
public class User
{
public int Id{ get; set; }

public required string UserName{ get; set; }
public required byte[] PasswordHash { get; set; } = [];
public required byte[] PasswordSalt { get; set; } = [];

public DateOnly DateOfBirth { get; set; }
public required string KnownAs{ get; set; }
public DateTime Created { get; set; } = DateTime.UtcNow;
public DateTime LastActive { get; set; } = DateTime.UtcNow;

public required string Gender { get; set; }
public string? Introduction { get; set; }
public string? Interests { get; set; }
public string? LookingFor { get; set; }

public required string City { get; set; }
public required string Country { get; set; }
public List<Photo> Photos { get; set; }

public int GetAge()
{
return DateOfBirth.CalculateAge();
}
}
}
c#
using API.Extensions;

namespace API.Entities
{
public class User
{
public int Id{ get; set; }

public required string UserName{ get; set; }
public required byte[] PasswordHash { get; set; } = [];
public required byte[] PasswordSalt { get; set; } = [];

public DateOnly DateOfBirth { get; set; }
public required string KnownAs{ get; set; }
public DateTime Created { get; set; } = DateTime.UtcNow;
public DateTime LastActive { get; set; } = DateTime.UtcNow;

public required string Gender { get; set; }
public string? Introduction { get; set; }
public string? Interests { get; set; }
public string? LookingFor { get; set; }

public required string City { get; set; }
public required string Country { get; set; }
public List<Photo> Photos { get; set; }

public int GetAge()
{
return DateOfBirth.CalculateAge();
}
}
}
Exception
fail: Program[0]
An error occurred during migration
System.Text.Json.JsonException: JSON deserialization for type 'API.Entities.User' was missing required properties, including the following: PasswordHash, PasswordSalt
at System.Text.Json.ThrowHelper.ThrowJsonException_JsonRequiredPropertyMissing(JsonTypeInfo parent, BitArray requiredPropertiesSet)
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, Boolean& isPopulatedValue)
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, Boolean& isPopulatedValue)
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`1 jsonTypeInfo, Nullable`1 actualByteCount)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at API.Data.Seed.SeedUsers(DataContext context) in C:\Users\pc\source\repos\DatingApp\API\Data\Seed.cs:line 19
at Program.<Main>$(String[] args) in C:\Users\pc\source\repos\DatingApp\API\Program.cs:line 30
fail: Program[0]
An error occurred during migration
System.Text.Json.JsonException: JSON deserialization for type 'API.Entities.User' was missing required properties, including the following: PasswordHash, PasswordSalt
at System.Text.Json.ThrowHelper.ThrowJsonException_JsonRequiredPropertyMissing(JsonTypeInfo parent, BitArray requiredPropertiesSet)
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, Boolean& isPopulatedValue)
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, Boolean& isPopulatedValue)
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`1 jsonTypeInfo, Nullable`1 actualByteCount)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at API.Data.Seed.SeedUsers(DataContext context) in C:\Users\pc\source\repos\DatingApp\API\Data\Seed.cs:line 19
at Program.<Main>$(String[] args) in C:\Users\pc\source\repos\DatingApp\API\Program.cs:line 30
Al3mid3x
Al3mid3x3mo ago
Json data file
Al3mid3x
Al3mid3x3mo ago
Seed Class
c#
using API.Entities;
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

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

var userData = await File.ReadAllTextAsync("Data/UserSeedData.json");

var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };

var users = JsonSerializer.Deserialize<List<User>>(userData, options);

if(users == null) return;

foreach (var user in users) {
using var hmac = new HMACSHA512();

user.UserName = user.UserName.ToLower();
user.PasswordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes("Pa$$w0rd"));
user.PasswordSalt = hmac.Key;

context.Users.Add(user);

}
await context.SaveChangesAsync();
}
}
}
c#
using API.Entities;
using Microsoft.EntityFrameworkCore;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

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

var userData = await File.ReadAllTextAsync("Data/UserSeedData.json");

var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };

var users = JsonSerializer.Deserialize<List<User>>(userData, options);

if(users == null) return;

foreach (var user in users) {
using var hmac = new HMACSHA512();

user.UserName = user.UserName.ToLower();
user.PasswordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes("Pa$$w0rd"));
user.PasswordSalt = hmac.Key;

context.Users.Add(user);

}
await context.SaveChangesAsync();
}
}
}
the error is happining because of the PasswordHash and PasswordSalt are not modified in the json folder but you can see that i have given them a value in the seed class and they already have a default value of an empty array in the User.cs class
MutableString
MutableString3mo ago
have you empirically tried to have those field in the json like
{
"PasswordHash": ""
...
}
{
"PasswordHash": ""
...
}
or even "PasswordHash": null i think it works i don't know how required behave with stj but maybe it's more strict than that
Gokul
Gokul3mo ago
the issue is in the User class you have marked PasswordHash and PasswordSalt as required, which means during deserialization it will expect a value to be present in the json, it doesnt matter if you set the values later on inside a for loop, the error states during deserialization its unable to find PasswordHash and PasswordSalt values . try removing required from User class and handling the required logic through code, else add empty string in json like "PasswordHash":"", "PasswordSalt":""
Want results from more Discord servers?
Add your server