我是MVC的新手并且有一点问题。所以基本上我有交货和交货,我有三个可以更新的属性:司机,车辆和状态。我遇到的问题是,当用户进入编辑交付屏幕时,他们会看到三个下拉列表,驱动程序,车辆(驾驶员和车辆根据可用性填充)和状态,现在这里是问题所在。
如果用户只想更新状态,则会更改状态并单击“保存”。但是,即使用户没有更改它,它也会更新到驱动程序和车辆下降状态。
例如:
如果当前的驱动程序是Sipho,而车辆xxx 123.如果用户想要将状态更改为已交付,他将进入编辑交付屏幕并将下拉菜单更改为“已交付”,但是驱动程序Gus和Vehicle yyy 123将在下拉列表中(因为它们当前可用)并且会将其更改为此驱动程序和车辆前夕,尽管用户不想更改它们。
我该如何避免这种情况?
这是我的观看代码:
@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);
}
答案 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" ../>
}