Object reference not set to an instance of an object. - ASP NET CORE Identity

0

Hej wszystkim.
Mam problem i nie potrafię sobie poradzić z nim. Przeszukałem google ale nie udało mi się znaleźć rozwiązania.
Mam model Customer

    public class CustomerModel : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string NIP { get; set; }
        [ForeignKey("Address")]
        public int AddressId { get; set; }
        public AddressModel Address { get; set; }
    }

A model Address wygląda następująco

    public class AddressModel
    {
        [Key]
        public int Id { get; set; }
        public string HouseNumber { get; set; }
        public string Street { get; set; }
        public string Town { get; set; }
        public string Voivodeship { get; set; }
        public string ZipCode { get; set; }
    }

W Register.cshtml.cs w klasie InputModel dodałem zmienne, które przechowują dane z inputów

            [Required]
            [StringLength(30, ErrorMessage = "{0} musi mieć co najmniej {2} i maksymalnie {1} znaków.", MinimumLength = 2)]
            [RegularExpression("^[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+$")]
            [Display(Name = "Miejscowość")]
            public string Town { get; set; }

            ... reszta kodu niżej ...

Następnie przypisuje do usera dane z formularza.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {
            returnUrl ??= Url.Content("~/");
            ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
            if (ModelState.IsValid)
            {
                var user = CreateUser();

                user.FirstName = Input.FirstName;
                user.LastName = Input.LastName;
                user.NIP = Input.NIP;
                user.Address.HouseNumber = Input.HouseNumber;
                user.Address.Street = Input.Street;
                user.Address.Town = Input.Town;
                user.Address.Voivodeship = Input.Voivodeship;
                user.Address.ZipCode = Input.ZipCode;

                await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
                await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);

                var result = await _userManager.CreateAsync(user, Input.Password);

                ... Reszta kodu niżej ...

I problem następuje w momencie kiedy próbuję przypisać dane z inputa do tabeli z klucza obcego (czyli np. user.Address.HouseNumber = Input.HouseNumber; -> Tutaj wywala błąd "Object reference not set to an instance of an object") A w user.FirstName bez problemu przypisuje wartość inputa.

Mógłby ktoś poradzić w jaki sposób rozwiązać ten problem?

5

Masz gdzieś nulla. Najlepiej sobie debuggerem przeledzic.
Najpewniej podczas CreateUser nie tworzysz obiektu dla właściwości Address. Daj tam gdzies user.Address = new AddressModel()

0
kzkzg napisał(a):

Najpewniej podczas CreateUser nie tworzysz obiektu dla właściwości Address. Daj tam gdzies user.Address = new AddressModel()

Dzięki. Gupek ze mnie.

0

@Captain Jack:
Przepraszam, nie jestem pewny, ale coś mi się nie zgadza. Mogę się mylić jak każdy człowiek, ale czy to jest logiczne aby tabela CustomerModel miała klucz obcy i była złączona tym kluczem z tabelą AddressModel??? Przecież to Customer może mieć Adres, a nie Adres ma mieć Customera. Moim zdaniem powinno być coś w stylu:

public class CustomerModel : IdentityUser
{
         public string FirstName { get; set; }
         public string LastName { get; set; }
         public string NIP { get; set; }
         public AddressModel? AddressModel { get; set; }
}
public class AddressModel
{
         [Key]
         public int Id { get; set; }
         public string HouseNumber { get; set; }
         public string Street { get; set; }
         public string Town { get; set; }
         public string Voivodeship { get; set; }
         public string ZipCode { get; set; }
         [ForeignKey("CustomerModel")]
         public string CustomerRefModelId { get;set; }
         public CustomerModel? CustomerModel { get;set; }
         
}

Tylko ważne, żeby dać znaki "?", bo inaczej nie będą się zapisywać w bazie dane.
Co do reszty kodu nie mam pewności, więc zostawiam pozostałym.

edit: usunąłem "?" z klucza referencyjnego, bo klucz referencyjny nie może być nullem.

0

@finito: w NET6.0
public string CustomerRefModelId { get;set; } EFCore potraktuje jako wartość która nie może byc null, a public string? CustomerRefModelId { get;set; } potraktuje jako wartość dopuszczającą null
(vs daje nawet ostrzeżenia co do tego)

i jak już lecimy Twoim przykładem, to w Customer powinno być public virtual List<AddressModel> AddressModels, ponieważ wiele adresów może mieć ustawionego tego samego Customer

0

@gswidwa1:

gswidwa1 napisał(a):

@finito: w NET6.0
public string CustomerRefModelId { get;set; } EFCore potraktuje jako wartość która nie może byc null, a public string? CustomerRefModelId { get;set; } potraktuje jako wartość dopuszczającą null
(vs daje nawet ostrzeżenia co do tego)

Yyy, znaczy właśnie to miałem na myśli. Przeczytaj "edit".

i jak już lecimy Twoim przykładem, to w Customer powinno być public virtual List<AddressModel> AddressModels, ponieważ wiele adresów może mieć ustawionego tego samego Customer

Tak wiem, ale już mi się nie chciało zmieniać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1