更新我的交付的建议

Advice for updating my deliveries

我是 MVC 的新手,遇到了一些小问题。所以基本上我有交付,在交付中我有三个可以更新的属性:Driver、车辆和状态。我遇到的问题是,当用户进入编辑交付屏幕时,他们会看到三个下拉列表,driver、车辆(Driver 和车辆根据可用性填充)和状态,现在在这里是哪里出了问题。

如果用户只想更新状态,他们将更改状态并单击保存。但随后它会更新到 driver 和车辆下拉列表中的内容,即使用户没有更改它也是如此。

例如:

如果当前 driver 是 Sipho,车辆 xxx 123。如果用户想要将状态更改为已交付,他将转到编辑交付屏幕并将下拉列表更改为 "Delivered"但是 Driver Gus 和 Vehicle yyy 123 将出现在下拉列表中(因为它们当前可用)并将其更改为此 driver 和 vehicle eve 尽管用户不想更改它们。

我怎样才能避免这种情况?

这是我的查看代码:

 @using (Html.BeginForm(new { delivery_date = Model.delivery_date }))
    {
        @Html.AntiForgeryToken()
    <section class="panel">
        <div class="panel-heading">Delivery Information</div>
        <div class="panel-body">
            <div class="form-horizontal">
                <hr />
                @Html.ValidationSummary(true)
                @Html.HiddenFor(model => model.DeliveryID)

                <div class="form-group">
                    @Html.LabelFor(model => model.EmployeeID, "Driver", new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.DropDownList("EmployeeID", null,htmlAttributes: new { @class = "form-control", id="employee" })
                        @Html.ValidationMessageFor(model => model.EmployeeID)
                    </div>
                </div>

                <div class="form-group">
                    @Html.LabelFor(model => model.VehicleID, "Truck", new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.DropDownList("VehicleID", null, htmlAttributes: new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.VehicleID)
                    </div>
                </div>


                <div class="form-group">
                    @Html.LabelFor(model => model.delivery_status, htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        <select class="form-control" data-val="true" data-val-required="The Status field is required." id="dropdown" name="delivery_status">

                            <option>Dispatched</option>
                            <option>Completed</option>
                            <option>Problem Encountered</option>
                        </select>
                        @Html.ValidationMessageFor(model => model.delivery_status, "", new { @class = "text-danger" })
                    </div>
                </div>
            </div>

        </div>
    </section>
            <section class="panel">

                <div class="panel-body">

                    <input type="submit" value="Save Changes" class="btn btn-default" style="float:right;" />
                    <a href="~/Delivery/Index" data-toggle="modal" class="btn  btn-info">
                        Back
                    </a>

                </div>
            </section>
    }

    <div class="form-group">
        @Html.HiddenFor(model => model.delivery_date, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.HiddenFor(model => model.delivery_date)
            @Html.ValidationMessageFor(model => model.delivery_date)
        </div>
    </div>

这是我的 Delivery Controller 编辑:

  // GET: /Delivery1/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            DELIVERY delivery = db.Delivery.Find(id);
            if (delivery == null)
            {
                return HttpNotFound();
            }
            ViewBag.EmployeeID = new SelectList(db.Employee.Where(o => o.employee_role == "Driver" && o.employee_status=="Available"), "EmployeeID", "employee_name");
            ViewBag.VehicleID = new SelectList(db.Vehicle.Where(o=> o.vehicle_status=="Available"), "VehicleID", "VehicleID");
            return View(delivery);
        }

        // POST: /Delivery1/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include="DeliveryID,EmployeeID,VehicleID,delivery_date,delivery_status")] DELIVERY delivery)
        {
            var order = from ord in db.Order where ord.DeliveryID == delivery.DeliveryID select ord;
            var vehicle = from ord in db.Vehicle where ord.VehicleID == delivery.VehicleID select ord;
            var employee = from ord in db.Employee where ord.EmployeeID == delivery.EmployeeID select ord;
            if(delivery.EmployeeID == null)
            {
                int Delivery = Convert.ToInt32 (from ord in db.Delivery where ord.DeliveryID == delivery.DeliveryID select ord.EmployeeID);
                delivery.EmployeeID = Delivery;
            }
            foreach (ORDER ord in order)
            {
                if (delivery.delivery_status.Equals("Completed"))
                {
                    ord.order_status = "Delivered";

                }
                else if (delivery.delivery_status.Equals("Dispatched"))
                {
                    ord.order_status = "Enroute";
                }
                else if (delivery.delivery_status.Equals("Problem Encountered"))
                {
                    ord.order_status = "Delayed";
                }
                // Insert any additional changes to column values.
            }
            foreach (VEHICLE ord in vehicle)
            {
                if (delivery.delivery_status.Equals("Completed"))
                {
                    ord.vehicle_status = "Available";
                }
                // Insert any additional changes to column values.
            }
            foreach (EMPLOYEE ord in employee)
            {
                if (delivery.delivery_status.Equals("Completed"))
                {
                    ord.employee_status = "Available";
                }
                // Insert any additional changes to column values.
            }
            db.SaveChanges();
            if (ModelState.IsValid)
            {
                db.Entry(delivery).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.EmployeeID = new SelectList(db.Employee, "EmployeeID", "employee_role", delivery.EmployeeID);
            ViewBag.VehicleID = new SelectList(db.Vehicle, "VehicleID", "vehicle_status", delivery.VehicleID);
            return View(delivery);
        }

主要问题是您没有强绑定到您的模型属性,因此,您的下拉列表中的第一个选项将是选定的(因为必须如此)。从您的评论来看,您似乎也没有在选项列表中包含当前的驱动程序,因此您需要调整查询以包含它。您应该首先创建一个视图模型来仅表示您需要的内容 display/edit

public class DeliveryVM
{
  public int ID { get; set; }
  public int Driver{ get; set; }
  public SelectList DriverList { get; set; }
  public int Truck { get; set; }
  public SelectList TruckList { get; set; }
  public string Status { get; set; }
  public SelectList StatusList { get; set; } 
}

然后在控制器中

public ActionResult Edit(int? id)
{
  ....
  Delivery delivery = db.Delivery.Find(id);
  ....
  DeliveryVM model = new DeliveryVM()
  {
    ID = delivery.DeliveryID,
    Driver = delivery.EmployeeID,
    // ditto for vehicle and status
  };
  ConfigureEditModel(model);
  return View(model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(DeliveryVM model) // no [Bind] attribute
{
  if (!ModelState.IsValid) // do this first
  {
    ConfigureEditModel(model);
    return View(model);
  }
  Delivery delivery = db.Delivery.Find(model.ID);
  // map the view model properties to the data model
  ...
  // save and redirect
}

private void ConfigureEditModel(DeliveryVM model)
{
  var statusList = new List<string>{ "Dispatched", "Completed", "Problem Encountered" };
  model.StatusList = new SelectList(statusList);
  // modify query to ensure the current driver is included
  var driverList =  db.Employee.Where(e => (e.employee_role == "Driver" && e.employee_status=="Available") || e.DriverID == delivery.DriverID);
  model.DriverList = new SelectList(driverList, "EmployeeID", "employee_name");
  // ditto for vehicles
}

并在视图中

@model DeliveryVM
....
@using(Html.BeginForm())
{
  @Html.HiddenFor(m => m.ID) // not required if you have the default route with ../{id}
  @Html.LabelFor(m => m.Driver)
  @Html.DropDownListFor(m => m.Driver, Model.DriverList) // the option matching the current Driver will be selected
  @Html.ValidationMessageFor(m => m.Driver)
  // ditto for Truck and Status
  <input type="submit" ../>
}