【问题标题】:DataAnnotations with EntityFramework (Database First) method使用 EntityFramework(数据库优先)方法的 DataAnnotations
【发布时间】:2011-08-23 19:33:24
【问题描述】:

我有一个项目,其中提供了一个数据库模型类以及一个单独的 EDMX EF 模型。在同一个解决方案中,我有一个 Web 服务,它与模型类一起访问这个项目。我希望模型类针对前端执行数据注释以进行验证,但根本没有得到验证。

为简洁起见,模型类(在我的模型项目中)如下。我的 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 执行此操作的文章,但我已看到 none 关于如何使用 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();
        }

【问题讨论】:

  • 您的 UI 使用的是什么?银光? WPF?
  • 您是否在使用 ModelState.IsValid 检查提交时模型的状态?
  • 按下提交按钮后,我将转到控制器中处理帖子并检查“If (ModelState.IsValid)”的方法,当它不应该时它总是正确的不是。我故意犯错误以查看验证是否被捕获。

标签: c# asp.net entity-framework-4 data-annotations


【解决方案1】:

不幸的是,这个注释似乎只影响渲染,而不是验证。我刚刚遇到了与 DataType.Url 相同的问题,并且在问题 Is the DataTypeAttribute validation working in MVC2? 中也进行了讨论(尽管对于 MVC 2 - 但问题在 3 中似乎相同)。

只需在上面放一个正则表达式数据注释:

[RegularExpression(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Email was invalid.")]

【讨论】:

    【解决方案2】:

    只是稍微扩展一下,在 MVC 3 中,您可以走另一条路线来使用验证。我首先使用 MVC 3 + EF 数据库,我可以在扩展/部分模型类中使用这样的代码:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-22
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多