I am learning C# and I have been running into a lot of issues with my first project around navigation properties. The main hurdle I am having an issue with is a basic four property model (and anything that includes a navigation property).
Here is the one I am currently working with:
Company Model:
public class Company
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
[Display(Name = "Id")]
public int Id { get; set; }
[Display(Name = "Name")]
public string Name { get; set; }
public CompanyType Type { get; set; }
public ICollection<Contact>? Contacts { get; set; }
}
Company Type Model:
public class CompanyType
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
[Display(Name = "Id")]
public int Id { get; set; }
[Display(Name = "Company Type")]
public string Type { get; set; } = "";
}
And here is my context - just simple.
public class SRMContext : DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<Contact> Contacts { get; set; }
public DbSet<CompanyType> CompanyTypes { get; set; }
public SRMContext (DbContextOptions<SRMContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Company>().ToTable("Companies");
modelBuilder.Entity<Contact>().ToTable("Contacts");
modelBuilder.Entity<CompanyType>().ToTable("CompanyTypes");
}
}
*I removed irrelevant models in the context.
I first used scaffolding to create the CRUD razor pages for Company. It would not include any navigation properties in it at all - for any model. Not sure if I am doing something wrong, or if this is standard. So I am trying to manually update the scaffolded pages to include CompanyType. I was able to generate a select list, and provide that to the UI. It gives me the options and I click submit. But when I click submit, it says I need to include the Company Type. If I change it to not required, it will submit, but there will be no company type listed.
I know you can just do the Id without doing the navigation property, but further in my code, I have many-to-many navigation properties, so the Id will not work for them. I am having the same issues with them too, but this one is much simpler to work with until I get this figured out.
What am I doing wrong?
public class CreateModel : PageModel
{
private readonly SRMContext _context;
public SelectList CompanyTypes { get; set; }
public CreateModel(SRMContext context)
{
_context = context;
}
public async Task<IActionResult> OnGetAsync()
{
CompanyTypes = new SelectList(_context.CompanyTypes, nameof(CompanyType.Id), nameof(CompanyType.Type));
return Page();
}
[BindProperty]
public Company Company { get; set; }
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Companies.Add(Company);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
View Page
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Company.Name" class="control-label"></label>
<input asp-for="Company.Name" class="form-control" />
<span asp-validation-for="Company.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Company.Type" class="control-label"></label>
<select asp-for="Company.Type" asp-items="Model.CompanyTypes" class="form-control"></select>
<span asp-validation-for="Company.Type" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
(I'm sorry, I know its a lot of code, but I want to show everything needed!)


Complex objects are not recognized on a form post, so the type is probably null. Instead, post the foreign key of the type and it should be recognized:
And in your form:
Haven't tested this, but pretty sure this is the issue.