【发布时间】:2012-10-15 22:36:03
【问题描述】:
MVC 验证基础(使用实体框架)
场景:
我有一个模型类如下(通过实体框架 EF.x DbContext 生成器自动生成)。
(目前没有视图模型)。
public partial class Activity
{
public int Id { get; set; }
public byte Progress { get; set; }
public decimal ValueInContractCurrency { get; set; }
public System.DateTime ForecastStart { get; set; }
public System.DateTime ForecastEnd { get; set; }
public int DepartmentId { get; set; }
public int OwnerId { get; set; }
public int StageId { get; set; }
public int StatusId { get; set; }
public virtual Department Department { get; set; }
public virtual Owner Owner { get; set; }
public virtual Stage Stage { get; set; }
public virtual Status Status { get; set; }
}
当我在强类型视图上提交空白表单时,我会收到以下验证消息:
进度字段是必需的。
ValueInContractCurrency 字段是必需的。
ForecastStart 字段是必需的。
ForecastEnd 字段是必需的。
即db 表中的所有字段。
如果我填写这些并再次提交,那么控制器就会被调用。由于 IsValid 为 false,控制器然后返回视图页面。
然后屏幕会重新显示这些验证消息:
StageId 字段是必需的。
DepartmentId 字段是必需的。
StatusId 字段是必需的。
OwnerId 字段是必需的。
即db 表中的所有外键字段(这些也是所有选择框)。
如果我填写了这些,表单就会成功提交并保存到数据库中。
问题:
鉴于我没有使用任何 [必需] 属性,验证从何而来?这和实体框架有关吗?
为什么表单不能立即在客户端验证所有内容,外键(或选择框)有什么不同,它们仅由 IsValid() 检查,即使它们是空的,因此显然无效?
如何使所有内容都在一个步骤中得到验证(对于空字段),这样用户就不必提交两次表单并且一次显示所有验证消息?是否必须关闭客户端验证?
(我尝试将 [Required] 属性添加到外键字段,但这似乎没有任何区别(可能它们只影响 IsValid)。我也尝试调用 Html.EnableClientValidation() 但这并没有也有任何区别)。
4..最后,我看到人们使用 [MetadataType[MetadataType(typeof(...)]] 进行验证。如果您有视图模型,为什么要这样做,或者只有在没有视图模型的情况下才这样做? ?
显然我在这里遗漏了一些基础知识,因此,如果有人知道关于 MVC 验证过程如何准确地逐步工作的详细教程,包括 javascript/controller 调用,而不仅仅是另一篇关于属性的文章,那么我也可以使用指向该链接的链接:c)
关于神秘人的更多信息:
解决方案设置如下:
.NET4
MVC3
EF5
EF5.x Db 上下文生成器
在 edmx 设计图面上使用“添加代码生成项”来关联 EF.x Db 上下文生成器文件(.tt 文件)
控制器如下所示:
// GET: /Activities/Create
public ActionResult Create()
{
ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "Name");
ViewBag.OwnerId = new SelectList(db.Owners, "Id", "ShortName");
ViewBag.ContractId = new SelectList(db.Contracts, "Id", "Number");
ViewBag.StageId = new SelectList(new List<string>());
ViewBag.StatusId = new SelectList(db.Status.Where(s => s.IsDefaultForNewActivity == true), "Id", "Name");
return View();
}
// POST: /Activities/Create
[HttpPost]
public ActionResult Create(Activity activity)
{
if (ModelState.IsValid)
{
db.Activities.Add(activity);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "Name");
ViewBag.OwnerId = new SelectList(db.Owners, "Id", "ShortName");
ViewBag.ContractId = new SelectList(db.Contracts, "Id", "Number");
ViewBag.StageId = new SelectList(db.Stages, "Id", "Number");
ViewBag.StatusId = new SelectList(db.Status, "Id", "Name");
return View(activity);
}
视图是这样的:
<!-- this refers to the EF.x DB Context class shown at the top of this post -->
@model RDMS.Activity
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Activity</legend>
<div class="editor-label">
@Html.LabelFor(model => model.StageId, "Stage")
</div>
<div class="editor-field">
@Html.DropDownList("StageId", String.Empty)
@Html.ValidationMessageFor(model => model.StageId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Progress)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Progress)
@Html.ValidationMessageFor(model => model.Progress)
</div>
<!-- ETC...-->
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
【问题讨论】:
-
顺便说一句,很抱歉在这里到处都是,但有点迷路了......
-
这里显然发生了其他事情。您所显示的不应给出这些结果。您是否在项目中添加了任何其他包?您是否使用任何自定义模型绑定器或值绑定器?你的行动方法是什么样的?获取和发布。
标签: asp.net-mvc asp.net-mvc-3 entity-framework-5 asp.net-mvc-validation