我正在为工作开发一个Web应用程序,并使用标准的CRUD风格交互。然而,有些字段我不希望用户更新,所以我从视图中将它们移除。但是,如果我没有明确设置这些字段,在模型在数据库中更新时,它们就会被清除。
我关心的是正确的填充ViewModels字段的方法。
我想到的大致思路是这样的:
我的视图模型:
public class EditSoftwareTrackingViewModel
{
public EditSoftwareTrackingViewModel(SoftwareTracking model)
{
Id = model.Id;
SoftwareId = model.SoftwareId;
ComputerId = model.ComputerId;
SoftwareActionId = model.SoftwareActionId;
LastModified = model.LastModified;
Computer = model.Computer;
Software = model.Software;
SoftwareAction = model.SoftwareAction;
}
public int Id { get; set; }
[DisplayName("Software")]
public int SoftwareId { get; set; }
[DisplayName("Computer")]
public int ComputerId { get; set; }
[DisplayName("Software Action")]
public int SoftwareActionId { get; set; }
[DisplayName("Last Modified")]
public DateTime? LastModified { get; set; }
public virtual Computer Computer { get; set; }
public virtual Software Software { get; set; }
public virtual SoftwareAction SoftwareAction { get; set; }
}
我的主要模型
[Table("asset.SoftwareTracking")]
public partial class SoftwareTracking
{
public int Id { get; set; }
[DisplayName("Software")]
public int SoftwareId { get; set; }
[DisplayName("Computer")]
public int ComputerId { get; set; }
[DisplayName("Date Entered")]
public DateTime? EnteredDate { get; set; }
[DisplayName("Software Action")]
public int SoftwareActionId { get; set; }
[DisplayName("Last Modified")]
public DateTime? LastModified { get; set; }
public virtual Computer Computer { get; set; }
public virtual Software Software { get; set; }
public virtual SoftwareAction SoftwareAction { get; set; }
}
我的控制器使用视图模型
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
EditSoftwareTrackingViewModel softwaretracking = new EditSoftwareTrackingViewModel(db.SoftwareTrackings.Find(id));
if (softwaretracking == null)
{
return HttpNotFound();
}
GeneratePageData(softwaretracking.Software.Id);
return View(softwaretracking);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EditSoftwareTrackingViewModel softwaretracking)
{
if (ModelState.IsValid)
{
softwaretracking.LastModified = DateTime.Now;
var softwareTrack = db.SoftwareTrackings.Find(softwaretracking.Id);
softwareTrack = new SoftwareTracking
{
Computer = softwaretracking.Computer,
ComputerId = softwaretracking.ComputerId,
LastModified = softwaretracking.LastModified,
Software = softwaretracking.Software,
SoftwareAction = softwaretracking.SoftwareAction,
SoftwareActionId = softwaretracking.SoftwareActionId,
SoftwareId = softwaretracking.SoftwareId,
EnteredDate = softwareTrack.EnteredDate
};
db.Entry(softwareTrack).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
GeneratePageData(softwaretracking.Software.Id);
return View(softwaretracking);
}
有更好的替代方案吗?还是我应该继续以这种方式创建我的视图模型?
编辑
我的业务逻辑和视图。
private void GeneratePageData(int? id = null)
{
ViewBag.Computers = new SelectList(db.Computers, "Id", "ComputerName");
ViewBag.SoftwareActions = new SelectList(db.SoftwareActions, "Id", "ActionPerformed");
var usedSoft = (from softTrack in db.SoftwareTrackings
where (softTrack.SoftwareActionId != 3)
select softTrack.Software);
var softwareList = (from soft in db.Softwares
where (
((from softTrack in db.SoftwareTrackings
where (softTrack.SoftwareActionId != 3 && softTrack.SoftwareId == soft.Id)
select softTrack.Software).Count() < soft.KeyQuantity)
&& !(soft.AssetStatusId == 4 || soft.AssetStatusId == 5)
|| soft.Id == id)
select soft).ToList();
ViewBag.SoftwareList = softwareList.Select(t => new SelectListItem
{
Text = t.SoftwareIdNameFull,
Value = t.Id.ToString()
});
}
我的观点是
@model Lighthouse_Asset_Manager.Models.EditSoftwareTrackingViewModel
@{
ViewBag.Title = "Edit Software Install";
Layout = "";
}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<h4 class="modal-title" id="myModalLabel">Edit Software Install</h4>
</div>
<div class="modal-body">
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "computerForm" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(model => model.Id)
<div class="form-horizontal">
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.SoftwareId, "Software", new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("SoftwareId", (IEnumerable<SelectListItem>)ViewBag.SoftwareList, "-- Select --", new
{
@style = "width:100%",
@class = "select2"
})
@Html.ValidationMessageFor(model => model.SoftwareId)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ComputerId, "Computer", new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("ComputerId", (IEnumerable<SelectListItem>)ViewBag.Computers, "-- Select --", new
{
@style = "width:100%",
@class = "select2"
})
@Html.ValidationMessageFor(model => model.ComputerId)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SoftwareActionId, "Action", new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("SoftwareActionId", (IEnumerable<SelectListItem>)ViewBag.SoftwareActions, "-- Select --", new
{
@style = "width:100%",
@class = "form-control"
})
@Html.ValidationMessageFor(model => model.SoftwareActionId)
</div>
</div>
<div class="form-actions no-color">
<button type="submit" class="btn btn-primary btn-sm"><i class="fa fa-floppy-o"></i> Edit Install Record</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
Cancel
</button>
</div>
</div>
}
</div>
SoftwareTracking
对象,并将您的视图模型属性映射到它,然后保存原始对象。顺便说一下:您不需要(也不应该)在POST方法中调用GeneratePageData(softwaretracking.Software.Id);
(基于原始模型重置视图模型属性是被忽略的)。 - user3559349SelectList
属性包含在视图模型中,而不是在ViewBag
中,你的视图模型包含一个似乎不必要的LastModified
属性(当你回传并保存数据模型时,在控制器中设置值即可 - 我假设这不是用户可以编辑的内容)。你还可以查看像 automapper 这样的工具,使其更加简单和清晰。 - user3559349SelectLists
属性,您仍然有一个通用的私有方法来分配这些属性,在GET和(假设您返回视图)POST方法中调用该方法。我使用类似于private void ConfigureEditModel(MyViewModel model) { model.MyFirstSelectList = someLinqQuery; }
的东西。 - user3559349ViewBag.SomeList = complex_query
,而是使用softwaretrackingView.SomeList = complex_query
。 - wal