Home > Mobile >  Razor pages: how to make a model with a foreign key
Razor pages: how to make a model with a foreign key

Time:02-18

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:

enter image description here

  • Related