我在使用实体框架的MVC3中工作。我有一个名为Product的实体,当用户添加新记录时,我想验证它的两个属性。为此,我创建了一个好友类,如下所示:
using System;
using System.ComponentModel.DataAnnotations;
namespace Rpm.Data.Partials
{
[MetadataType(typeof(ProductMetadata))]
public partial class Product
{
}
}
元数据类如下:
using System;
using System.ComponentModel.DataAnnotations;
namespace Rpm.Data.Partials
{
public class ProductMetadata
{
[Required]
public string ProductName { get; set; }
[Range(200, 1000, ErrorMessage = "You must select a valid Account Type")]
public int AccountTypeId { get; set; }
}
}
允许用户添加新记录的视图如下:
@model Rpm.Data.Product
@{
ViewBag.Title = "Product"
}
<script type="text/javascript">
$(document).ready(function() {
//There should be no selection in the drop-down box when the form is first displayed.
document.getElementsByTagName("select")[0].selectedIndex = -1;
}
function formSubmit() {
var form = $("form");
if (form.valid()) {
(event.preventDefault) ? event.preventDefault() : event.returnValue = false;
document.getElementById("frmNewProduct").submit();
return true;
}
else {
return false;
}
}
</script>
<h2>Add New Product</h2>
@using (Html.BeginForm("Create", "Product", new { id = new Product() }, FormMethod.Post, new { id = "frmNewProduct" }))
{
@Html.ValidationSummary(true)
<table>
<tr>
<td>
Product Name
</td>
<td>
@Html.TextBoxFor(m => new Product().ProductName)
@Html.ValidationMessageFor(m => new Product().AccountTypeId)
</td>
</tr>
<tr>
<td>
Account Type
</td>
<td>
@Html.DropDownListFor(m => new Product().AccountTypeId, new SelectList(Lookup.Instance.AccountTypes, "AccountTypeId", "AccountTypeName"))
@Html.ValidationMessageFor(m => new Product().AccountTypeId)
</td>
</tr>
<tr>
<td />
<td>
<input type="image" src="@Url.Content("~/Content/images/savebutton.png")" onclick="return formSubmit()" />
</td>
</tr>
</table>
}
(当然,上面的内容非常简化,只是为了避免帖子中出现与实际无关的代码过载。)
问题是,当用户单击"保存"按钮时,ProductName的验证会很好地启动,如果字段为空,则会显示验证消息;但是,AccountTypeId的消息永远不会显示,即使下拉列表没有选择(selectedIndex == -1)
。我知道AccountTypeId上的RangeAttribute
正在被提取,因为当EF试图保存对实体的更改时,它会抛出一个DbEntityValidationException
,而ErrorMessage的文本是我在元数据中指定的自定义错误消息。我只是似乎无法将其显示在页面上,导致表单验证失败,从而阻止用户保存。
任何关于我做错了什么的建议都将不胜感激!
TIA,
Jeff
执行此操作时:
@Html.TextBoxFor(m => new Product().ProductName)
@Html.ValidationMessageFor(m => new Product().AccountTypeId)
您将创建两个完全不同的Product()实例,并为每个属性创建额外的Product实例。这可能会起作用,因为MVC只是使用lambda来创建布局格式,但它通常效率不高,而且会浪费内存。
您的型号已经是产品。您应该只使用m => m.ProductName
这可能会混淆验证系统。我会按照我的建议去做,看看问题是否还会继续。
您也不需要javascript来设置dropdownlist类型。只需这样做:
@Html.DropDownListFor(m => new Product().AccountTypeId,
new SelectList(Lookup.Instance.AccountTypes,
"AccountTypeId", "AccountTypeName"), "Select")
并确保AccountTypeId是可为null的int,并在其上放置[Required]
属性。验证器将确保有一个值。
我也不知道你为什么要使用formSubmit代码。图像输入已经是提交类型,所以当你点击它们时,它们就会提交表单。除了再次提交表单之外,您似乎没有做任何其他事情。