I'm doing a small project using Razor pages. It's about cars. So I've created two scaffolded items from two classes: Maker
and Model
.
This is the Maker
class
public class Maker
{
public int Id { get; set; }
public string Name { get; set; }
}
And this is the Model
class
public class Model
{
public int Id { get; set; }
public Maker Maker { get; set; }
public string Name { get; set; }
}
public class CreateModel : PageModel
{
private readonly ArchivioItalianeDaCorsa.Data.ApplicationDbContext _context;
public List<SelectListItem> makers { get; set; }
public CreateModel(ArchivioItalianeDaCorsa.Data.ApplicationDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
caseAutomobilistiche = _context.makers.Select(maker => new
SelectListItem
{
Text = maker.Name,
Value = maker.Id.ToString()
}).ToList();
return Page();
}
[BindProperty]
public Modello Modello { get; set; }
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Model.Add(Modello);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
And last but not the least, the html
<h1>Create</h1>
<h4>Modello</h4>
<hr />
<div >
<div >
<form method="post">
<div asp-validation-summary="ModelOnly" ></div>
<div >
<label asp-for="Model.Maker" ></label>
<select aria-label="Marca select" asp-items="Model.makers" asp-for="Model.Maker" name="Marca">
<option>Seleziona una marca</option>
</select>
<label asp-for="Model.Name" ></label>
<input asp-for="Model.Name" />
<span asp-validation-for="Model.Name" ></span>
</div>
<div >
<input type="submit" value="Create" />
</div>
</form>
</div>
</div>
My problem appears when I try to create a new Model
. In onGet
I query the database to show all the possible makers in a select tag, but I can't bind the choice to the object that needs to be saved.
Is the class Model
wrong?
PS: the code was initially written in Italian, I've translated it while asking the question so if something is not clear let me know and I will fix the question
CodePudding user response:
In your select list item, the value in the option field is the Maker.Id
, hence the value being passed to your model is an integer, not the object.
It's better to be explicit when writing your constraints, rewrite your Model
class like this;
public class Model
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public int MakerId { get; set; }
[ForeignKey("MakerId")]
public Maker Maker { get; set; }
}
In the code above, we are explicitly instructing entity framework that Model has a non nullable foreign key MakerId. This property will be a column in the database wherein you'll be able to save the value from your select list.
Try to scaffold a new razor page after rewriting your models.
CodePudding user response:
asp-items="Model.makers" asp-for="Model.Maker" name="Marca"
1.According to asp-items="Model.makers"
in your html , you use makers to bind data. In your OnGet
, change caseAutomobilistiche into makers
2.Delete name attribute , because asp-for
will generate name to bind the data .
3.change asp-for="Model.Maker"
into asp-for="Model.Maker.Id"
You can get MakerId,then do your other things.
Result: