Search code examples
asp.net-corerazordrop-down-menucrudselectlist

How to post data to an Asp.net razor page app


I am trying to do a CRUD in ASP.net 6 but having difficulties posting my data to the data base. I believe my form data is not valid because of my select lists but I am not sure. The following is how my code looks.

 public class CreateModel : StudentSelectListPageModel
    {
        private readonly ThreeTierAdvisementApp.Data.AdvisementDbContext _context;

        public CreateModel(ThreeTierAdvisementApp.Data.AdvisementDbContext context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            PopulateDropDownList(_context);
     
            return Page();
        }

        [BindProperty]
        public Student Student { get; set; }


        // To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
        public async Task<IActionResult> OnPostAsync()
        {
            var emptyStudent = new Student();
            var emptyAdvisor = new Advisor();
            //var emptyMajor = new Major();

            if (await TryUpdateModelAsync<Student>(
                emptyStudent, "student",
                s => s.ID, s => s.Name, s => s.Address, s => s.PhoneNumber, s => s.Email, s => s.Major, s => s.Status, s => s.Advisor))
            {
                _context.Students.Add(emptyStudent);
                await _context.SaveChangesAsync();
                return RedirectToPage("./Index");
            }

            PopulateDropDownList(_context);

            return Page();
        }
    }

 public class StudentSelectListPageModel : PageModel
    {
        public SelectList AdvisementNameSL { get; set; }
        public SelectList MajorNameSL { get; set; }
        public SelectList StatusNameSL { get; set; }


        public void PopulateDropDownList(AdvisementDbContext _context)
        {
            var advisorQuery = from d in _context.Advisors
                               orderby d.Name // Sort by name.
                               select d;

            var majorQuery = from d in _context.Students
                             orderby d.Major // Sort by name.
                             select d;

            var statusQuery = from d in _context.Students
                              orderby d.Name // Sort by name.
                              select d;

            AdvisementNameSL = new SelectList(advisorQuery.AsNoTracking(),
                        "ID", "Name");

            MajorNameSL = new SelectList(majorQuery.AsNoTracking(),
                        "ID", "MajorID");

            StatusNameSL = new SelectList(statusQuery.AsNoTracking(),
                      "ID", "Status");
        }
    }

 <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Student.ID" class="control-label"></label>
                <input asp-for="Student.ID" class="form-control" />
                <span asp-validation-for="Student.ID" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Student.Name" class="control-label"></label>
                <input asp-for="Student.Name" class="form-control" />
                <span asp-validation-for="Student.Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Student.Address" class="control-label"></label>
                <input asp-for="Student.Address" class="form-control" />
                <span asp-validation-for="Student.Address" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Student.PhoneNumber" class="control-label"></label>
                <input asp-for="Student.PhoneNumber" class="form-control" />
                <span asp-validation-for="Student.PhoneNumber" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Student.Email" class="control-label"></label>
                <input asp-for="Student.Email" class="form-control" />
                <span asp-validation-for="Student.Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Student.MajorID" class="control-label"></label>
                <select asp-for="Student.Major" class="form-control" asp-items="@Model.MajorNameSL"><option value="">-- Select Major --</option></select>
            </div>
            <div class="form-group">
                <label asp-for="Student.Status" class="control-label"></label>
                <select asp-for="Student.ID" class="form-control" asp-items="@Model.StatusNameSL"><option value="">-- Select Status --</option></select>
                <span asp-validation-for="Student.Status"  class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Student.AdvisorID" class="control-label"></label>
                <select asp-for="Student.AdvisorID" class="form-control" asp-items="@Model.AdvisementNameSL"><option value="">-- Select Advisor --</option></select>
            </div>
           
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>

When I try debug I notice only the single inputs are populating but the dropdown menus are not. Can I get guidance how to set the drop downs properly.


Solution

  • Acordding to:

    For public SelectList(IEnumerable items, string dataValueField, string dataTextField);, the first parameter is the source, the second parameter is each option value in select, the third parameter is each option text in html.

    Model Binding will send the selected value to backend, and it binds the value by match the property in the backend with the name attribute in the frontend.

    1.Be sure the dataValueField and dataTextField you set are existed property in the model, also the property should be simple type data instead of complex model.

    2.The select corresponding asp-for should also be simple type property instead of model.

    3.The three dropdown you set with the same dataValueField(ID), the data you send to backend are always be the ID you selected which may not match your requirement.

    e.g.

    <div class="form-group">
         <label asp-for="Student.AdvisorID" class="control-label"></label>
         <select asp-for="Student.AdvisorID" class="form-control" asp-items="@Model.AdvisementNameSL"><option value="">-- Select Advisor --</option></select>
    </div>
    

    The corresponding backend code for store AdvisementNameSL should be:

    AdvisementNameSL = new SelectList(advisorQuery.AsNoTracking(),
                "AdvisorID", "Name");