建议更新我的交货

时间:2015-09-03 00:55:29

标签: asp.net-mvc editing

我是MVC的新手并且有一点问题。所以基本上我有交货和交货,我有三个可以更新的属性:司机,车辆和状态。我遇到的问题是,当用户进入编辑交付屏幕时,他们会看到三个下拉列表,驱动程序,车辆(驾驶员和车辆根据可用性填充)和状态,现在这里是问题所在。

如果用户只想更新状态,则会更改状态并单击“保存”。但是,即使用户没有更改它,它也会更新到驱动程序和车辆下降状态。

例如:

如果当前的驱动程序是Sipho,而车辆xxx 123.如果用户想要将状态更改为已交付,他将进入编辑交付屏幕并将下拉菜单更改为“已交付”,但是驱动程序Gus和Vehicle yyy 123将在下拉列表中(因为它们当前可用)并且会将其更改为此驱动程序和车辆前夕,尽管用户不想更改它们。

我该如何避免这种情况?

Here is a screen shot of the edit screen:

这是我的观看代码:

 @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);
        }

1 个答案:

答案 0 :(得分:1)

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

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" ../>
}