I have created a Razor Pages project and I have created a data model called company
and modified the User Identity to have a relationship to company.
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string Surname { get; set; }
public Company Company { get; set; }
}
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public string AccessCode { get; set; }
public ICollection<ApplicationUser> Employees { get; set; }
}
Using the below code I am able to create a Company and assign that Company to the user
Company c = new Company { Name = Input.Name };
_context.Companies.Add(c);
await _context.SaveChangesAsync();
ApplicationUser u = await _userManager.GetUserAsync(User);
u.Company = c;
await _context.SaveChangesAsync();
So I am able to create a company and link the Company to the User however when I try and check if the current user has a Company associated with it using the below code it fails to get the Company, x.Company
returns Null even though there is a company linked to the current user
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Fleet_Man.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Fleet_Man.Pages
{
public class CompanyModel : PageModel
{
private readonly UserManager<ApplicationUser> _userManager;
ApplicationDbContext _context;
public CompanyModel(UserManager<ApplicationUser> userManager, ApplicationDbContext appDbContext)
{
_userManager = userManager;
_context = appDbContext;
}
public Boolean CompanyMember { get; set; }
[BindProperty]
public InputModel Input { get; set; }
public string ReturnUrl { get; set; }
public string Message { get; set; }
public class InputModel
{
[Required]
[Display(Name = "Company Name")]
public string Name { get; set; }
}
public async Task<IActionResult> OnGetAsync(string returnUrl = null)
{
//ApplicationUser x = await _userManager.GetUserAsync(User);
//Updated to reflect suggestion below
ApplicationUser x = await _userManager.GetUserAsync(User).Inlcude(u => u.Company).FirstOrDefaultAsync(u => u.FirstName == User);
ReturnUrl = returnUrl;
if (x.Company == null)
{
CompanyMember = false;
Message = "You don't belong to a company.";
}
else
{
CompanyMember = true;
Message = "You belong to a company.";
}
return Page();
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
if (ModelState.IsValid)
{
ReturnUrl = returnUrl;
Company c = new Company { Name = Input.Name };
_context.Companies.Add(c);
await _context.SaveChangesAsync();
ApplicationUser u = await _userManager.GetUserAsync(User);
u.Company = c;
await _context.SaveChangesAsync();
//var p = new Patient { Title = Input.Title, FirstName = Input.FirstName, Surname = Input.Surname, DOB = Input.DOB, NHSNumber = Input.NHSNumber };
//_context.Patients.Add(p);
//await _context.SaveChangesAsync();
//Message = "Patient (" + Input.FirstName + " " + Input.Surname + ") created successfully";
//return RedirectToPage("AllPatients");
}
return Page();
}
}
}
Linked entities are not returned automatically. You need to use one of the strategy described here: Loading Related Data
I don't have implementation details of _userManager
but I assume you need to change it something like this
public async ApplicationUser GetUserAsync(string User) =>
await _context.Users
.Inlcude(u => u.Company) // explicitly load Company
.FirstOrDefaultAsync(u => u.FirstName == User)
If you use .net core UserManager then you can't modify its code, but you can still load referenced entity as described in the link I posted above:
var x = await _userManager.GetUserAsync(User)
_context.Entry(x)
.Reference(b => b.Company)
.Load();