使用ViewModel替代直接数据实现航班预订下拉框数据加载问题
Hey, let's figure out why your dropdowns aren't loading data when integrating the ViewModel into your flight booking system. Here's the breakdown of the issues and step-by-step fixes:
1. Mismatched Model Type in View
Your current view is using the WebSite.Data.FlightBooking entity as its model, but you're trying to work with FlightBookingViewModel. This mismatch is one of the core reasons your dropdowns aren't behaving correctly.
2. Errors in Controller's Post Method
Looking at your HttpPost Create method, there are several typos and incorrect references:
- You're using
_context.Customersinstead of_context.Passengersfor the passenger dropdown - You're referencing
_context.Eventsinstead of_context.Flightsfor the flight dropdown - The selected value parameters are wrong (
model.IdFfor passenger dropdown,model.IdEwhich doesn't exist for flights)
3. ViewModel and View Binding Gaps
Your ViewModel has an Email field that wasn't being used in the view, and the Name field was incorrectly typed as int (flight names should be strings). Also, the Attended field was missing from your ViewModel but present in the view.
Fixed Code Examples
Updated ViewModel
First, fix the ViewModel to match your needs (correct data types and missing fields):
namespace WebSite.Models.PassengerViewModels { public class FlightBookingViewModel { [Display(Name = "Passenger ID ")] public int IdC { get; set; } [Display(Name = "E-mail Address ")] [Required] [DataType(DataType.EmailAddress)] public string Email { get; set; } [Display(Name = "Flight ID ")] public int IdF { get; set; } [Display(Name = "Flight Name ")] public string FlightName { get; set; } // Changed from int to string public bool Attended { get; set; } // Added to match view's checkbox } }
Updated Controller
Adjust the controller to work with the ViewModel, fix the dropdown data population, and map the ViewModel to your entity:
// GET: FlightBookings/Create public IActionResult Create() { // Populate dropdowns with correct data sources ViewData["IdC"] = new SelectList(_context.Passengers, "Id", "Email"); ViewData["IdF"] = new SelectList(_context.Flights, "Id", "Name"); // Pass an empty ViewModel to the view return View(new FlightBookingViewModel()); } // POST: FlightBookings/Create [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("IdC,IdF,Attended,Email")] FlightBookingViewModel model) { if (ModelState.IsValid) { // Map ViewModel properties to your FlightBooking entity var flightBooking = new FlightBooking { IdC = model.IdC, IdF = model.IdF, Attended = model.Attended // Add any other required entity fields here }; _context.Add(flightBooking); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } // Re-populate dropdowns with the selected values if validation fails ViewData["IdC"] = new SelectList(_context.Passengers, "Id", "Email", model.IdC); ViewData["IdF"] = new SelectList(_context.Flights, "Id", "Name", model.IdF); return View(model); }
Updated View
Update the view to use the ViewModel and bind all necessary fields:
@model WebSite.Models.PassengerViewModels.FlightBookingViewModel @{ ViewData["Title"] = "Create"; } <h2>Create</h2> <h4>Flight Booking</h4> <hr /> <div class="row"> <div class="col-md-4"> <form asp-action="Create"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="IdC" class="control-label"></label> <select asp-for="IdC" class="form-control" asp-items="ViewBag.IdC"></select> <span asp-validation-for="IdC" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Email" class="control-label"></label> <input asp-for="Email" class="form-control" /> <span asp-validation-for="Email" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="IdF" class="control-label"></label> <select asp-for="IdF" class="form-control" asp-items="ViewBag.IdF"></select> <span asp-validation-for="IdF" class="text-danger"></span> </div> <div class="form-group"> <div class="checkbox"> <label> <input asp-for="Attended" /> @Html.DisplayNameFor(model => model.Attended) </label> </div> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-default" /> </div> </form> </div> </div> <div> <a asp-action="Index">Back to List</a> </div> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} }
Key Takeaways
- Always ensure your view's
@modelmatches the ViewModel you're passing from the controller - Double-check your controller's data sources and selected value parameters when repopulating dropdowns after validation fails
- Map ViewModel properties correctly to your database entity before saving to the context
内容的提问来源于stack exchange,提问作者Sami-M




