You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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.Customers instead of _context.Passengers for the passenger dropdown
  • You're referencing _context.Events instead of _context.Flights for the flight dropdown
  • The selected value parameters are wrong (model.IdF for passenger dropdown, model.IdE which 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 @model matches 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

火山引擎 最新活动