gpt4 book ai didi

c# - 填充 ViewModel 的正确方法?

转载 作者:行者123 更新时间:2023-11-30 13:56:29 26 4
gpt4 key购买 nike

我正在为工作开发一个网络应用程序,并且我正在使用标准的 CRUD 样式交互。但是,有些字段我不希望用户更新,因此我将它们从 View 中删除。但是,如果我没有显式设置这些字段,当模型在数据库中更新时它们会被清除。

我很关心为我的 ViewModels 填充字段的正确方法是什么。

我的粗略想法是这样的:

我的 View 模型:

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

我的 Controller 使用 View 模型

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

有更好的选择吗?或者我应该继续以这种方式创建我的 View 模型吗?

编辑

我的业务逻辑和 View

    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">
&times;
</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>

最佳答案

您使用 View 模型的方法很好。 this question的答案解释了一些好处,包括防止过度发布攻击、使用特定于 View 的显示和验证属性以及包括特定于 View 的属性,例如 SelectListsautomapper等工具可以轻松地在您的数据和 View 模型之间进行映射,并减少 Controller 中的代码。我建议对您的 View 模型进行一些更改。 LastModifiedComputerSoftwareSoftwareAction 属性不是必需的(您没有绑定(bind)到这些),我将在模型中包含 SelectList 属性而不是 ViewBag

查看模型

public class EditSoftwareTrackingViewModel 
{
public int Id { get; set; }
[Display(Name="Software")]
public int SoftwareId { get; set; }
[Display(Name="Computer")]
public int ComputerId { get; set; }
[Display(Name="Software Action")]
public int SoftwareActionId { get; set; }
public SelectList Computers { get; set; }
public SelectList SoftwareActions{ get; set; }
public SelectList SoftwareList{ get; set; }
}

然后更改 GeneratePageData() 方法以接受 View 模型

private void GeneratePageData(EditSoftwareTrackingViewModel model)
{
model.Computers = new SelectList(db.Computers, "Id", "ComputerName");
....

并且在 View 中(总是最好使用强类型的助手)

@Html.DropDownListFor(m => m.SoftwareId, Model.SoftwareList, "-- Select --", new { @class = "select2" })

还有一些需要注意的事情。

  • 您应该使用 [Display(Name="..")] 属性(不是[显示名称(..)])
  • 当您设置 LastModified 属性时,您应该考虑使用UCT 时间。
  • Id 属性的隐藏输入在 View 中不是必需的(假设您使用默认的 {controller}/{action}/{id} 路由mapping) - 它被添加到路由值中并且无论如何都会被绑定(bind)
  • 除非您特别需要表单的 id 属性,否则您可以只需使用 @using(Html.BeginForm()) {
  • 您不需要 LabelFor() 中的第二个参数 - 它可以只是Html.LabelFor(m => m.SoftwareId, new { @class = "control-label
    col-md-2"})
    因为您已经在 [Display] 中指定了它属性

最后,如果您想进一步简化您的 View ,您可以考虑自定义 EditorTemplates 或 html 助手,如 this answer 中所示这将允许您替换

<div class="form-group">
@Html.LabelFor(model => model.SoftwareId, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.SoftwareId, Model.SoftwareList, "-- Select --", new { @class = "select2" })
@Html.ValidationMessageFor(model => model.SoftwareId)
</div>
</div>

与(自定义 EditorTemplate)

@Html.EditorFor(m => m.SoftwareId, "BootstrapSelect", Model.SoftwareList)

或(自定义 HtmlHelper)

@Html.BootstrapDropDownFor(m => m.SoftwareId, Model.SoftwareList)

关于c# - 填充 ViewModel 的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27995671/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com