我有一个项目,其中提供了一个数据库模型类以及一个单独的EDMX EF模型。在同一个解决方案中,我有一个Web服务,它与模型类一起访问该项目。我希望模型类针对前端执行数据注释以进行验证,但是根本没有得到验证。
为简洁起见,模型类(在我的Model项目中)如下所示。我的Web服务引用此类并用作接口。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;
[DataContract]
[MetadataType(typeof(CustomerMetaData))]
public partial class Customer
{
}
public class CustomerMetaData
{
[DataMember]
public object CustomerID { get; set; }
[Required]
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public object Email { get; set; }
}
当我点击表单上的“提交”按钮时,它会尝试添加记录,但不会进行任何验证。发生运行时错误,通知我需要电子邮件地址。我显然希望通过数据注释预先完成此验证。
我该如何做到这一点?
实际的运行时错误正在回来,说当尝试添加记录时,电子邮件地址不应为NULL。这是对的。数据库列需要一个值。
我认为通过在模型中使用数据注释,如果前端出现问题并且一旦表单尝试发布时模型无效,则相应的数据注释错误应显示在表单上。我的印象是没有必要编写任何特定的客户端验证。该模型应该为您照顾。我在这个假设中是不正确的吗?
网上有一些文章如何使用 CodeFirst 执行此操作,但我已经看到无如何使用 DataBaseFirst 执行此操作。如何实现这一目标?
我的客户课程再次如下。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace YeagerTechModel
{
[Serializable]
[DataContract]
//[MetadataType(typeof(CustomerMetaData))]
public partial class Customer
{
public Customer()
{
this.Projects = new HashSet<Project>();
}
[DataMember]
public short CustomerID { get; set; }
[Required]
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public string Email { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Company { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string FirstName { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string LastName { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Address1 { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string Address2 { get; set; }
[StringLength(50)]
[DataType(DataType.Text)]
[DataMember]
public string City { get; set; }
[StringLength(2)]
[DataType(DataType.Text)]
[DataMember]
public string State { get; set; }
[StringLength(10)]
[DataType(DataType.Text)]
[RegularExpression(@"^\d{5}(-\d{4})?$")]
[DataMember]
public string Zip { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[DataMember]
public string HomePhone { get; set; }
[StringLength(12)]
[DataType(DataType.PhoneNumber)]
[DataMember]
public string CellPhone { get; set; }
[StringLength(100)]
[DataType(DataType.Url)]
[DataMember]
public string Website { get; set; }
[StringLength(50)]
[DataType(DataType.EmailAddress)]
[DataMember]
public string IMAddress { get; set; }
[DataMember]
public System.DateTime CreatedDate { get; set; }
[DataMember]
public Nullable<System.DateTime> UpdatedDate { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
}
当我在客户端调试“if(ModelState.IsValid)”时,该属性始终返回true。就好像DataAnnotations甚至没有被识别一样。在调试时,我检查了ModelState对象,并且它具有所有属性值(在所有情况下都是空字符串,因为我试图强制发生错误)。我应该在电子邮件地址上收到isRequired错误,我故意留空。
[HttpPost]
public ActionResult Create(YeagerTechWcfService.Customer cust)
{
if (ModelState.IsValid)
{
try
{
db.AddCustomer(cust);
TempData["ErrCode"] = "Customer successfully added.";
return RedirectToAction("Index", "Home");
}
catch (Exception ex)
{
ViewData["ErrCode"] = "CustErr";
ViewBag.Error = ex.Message;
return View();
}
}
else
return View();
}
答案 0 :(得分:1)
不幸的是,这个注释只会影响渲染,而不会影响验证。我刚刚遇到了与DataType.Url相同的问题,它也在问题Is the DataTypeAttribute validation working in MVC2?中讨论过(虽然对于MVC 2 - 但问题在3中看起来是一样的。)
只需删除正则表达式数据注释:
[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Email was invalid.")]
答案 1 :(得分:0)
为了扩展这一点,在MVC 3中你可以使用另一条路径来使用验证。我首先使用MVC 3 + EF数据库,我可以在扩展/部分Model类中使用这样的代码:
[MetadataType(typeof(Foobar.Metadata))]
[Serializable]
public partial class Foobar
{
private sealed class Metadata
{
[Required]
[MinLength(10)]
public object Name { get; set; }
}
// Other stuff here
}
然后,当我可以在控制器动作中为我的小Foobar提供一个无效的名称时,我可以通过使用TryValidateModel而不是ModelState.IsValid(恐怖的恐怖,我没有数据绑定)很好地得到验证错误。
Foobar c = new Foobar();
c.Name = "ponies";
var y = TryValidateModel(c);
if (!y)
{
foreach (var item in ModelState.Values)
{
foreach (var err in item.Errors)
{
DoxLog.Error(err.ErrorMessage, err.Exception);
}
}
}