更新我的交付的建议
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" ../>
}
我是 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" ../>
}