当表单字段留空时,NerdDinner 表单验证 MVC2 中的 DataAnnotations 错误

发布于 2024-09-14 06:17:18 字数 6509 浏览 2 评论 0原文

平台:Windows 7 Ultimate
IDE:Visual Studio 2010 Ultimate
Web 环境: ASP.NET MVC 2
数据库: SQL Server 2008 R2 Express
数据访问:实体框架 4
表单验证:数据注释
示例应用:来自 Wrox Pro ASP.NET MVC 2 的 NerdDinner
书籍: Wrox Professional MVC 2
第 1 章 - 部分的问题: “将验证和业务规则逻辑与模型类集成”(第 33 至 35 页)

错误概要: NerdDinner 表单数据注释和数据库空值验证错误。

当数据库字段设置为不允许空值时,示例代码中的 DataAnnotations 不起作用。

书中的代码和从 codeplex 下载的示例代码出现错误。

救命!我对此真的很沮丧!我不敢相信这么简单的东西竟然不起作用???

重现错误的步骤:

  1. 将数据库字段设置为不允许 NULL (见图)
  2. 设置 NerdDinnerEntityModel 晚餐类字段' 可空属性为 false (参见图片)
  3. 为 Dining_Validation 类添加 DataAnnotations (代码 A)
  4. 创建 Dining 存储库类 (代码 B)
  5. 添加 CREATE 操作DiningController (CODE C)
  6. 这是发布前的空白表单(参见图片)
  7. 发布时出现此空错误 空白表格应该是 由Dinner_Validation类拦截 数据注释。 注意错误消息 说“这个财产不能 设置为空值。 WTH??? (见图)
  8. 编辑过程中出现下一个错误 过程。这是编辑控制器 操作(代码D)
  9. 这是故意错误的“编辑”形式 输入测试晚餐验证 DataAnnotations (见图)
  10. 发布时再次出现错误 编辑具有空白表单字段的表单。发帖请求 应该被Dinner_Validation 类DataAnnotations 拦截。相同的 空输入错误。啥??? (参见图片)

查看屏幕截图:

http://www.intermedia4web.com/temp/nerdDinner/StackOverflowNerdDinnerQuestionshort.png

代码 A:

    [MetadataType(typeof(Dinner_Validation))]
    public partial class Dinner { }

    [Bind(Include = "Title, EventDate, Description, Address, Country, ContactPhone, Latitude, Longitude")] 
    public class Dinner_Validation
    {
        [Required(ErrorMessage = "Title is required")]
        [StringLength(50, ErrorMessage = "Title may not be longer than 50 characters")]
        public string Title { get; set; }

        [Required(ErrorMessage = "Description is required")]
        [StringLength(265, ErrorMessage = "Description must be 256 characters or less")]
        public string Description { get; set; }

        [Required(ErrorMessage="Event date is required")]
        public DateTime EventDate { get; set; }

        [Required(ErrorMessage = "Address is required")]
        public string Address { get; set; }

        [Required(ErrorMessage = "Country is required")]
        public string Country { get; set; }

        [Required(ErrorMessage = "Contact phone is required")]
        public string ContactPhone { get; set; }

        [Required(ErrorMessage = "Latitude is required")]
        public double Latitude { get; set; }

        [Required(ErrorMessage = "Longitude is required")]
        public double Longitude { get; set; }
    }

代码 B:

    public class DinnerRepository
    {
        private NerdDinnerEntities _NerdDinnerEntity = new NerdDinnerEntities();

        // Query Method
        public IQueryable<Dinner> FindAllDinners()
        {
            return _NerdDinnerEntity.Dinners;
        }

        // Query Method
        public IQueryable<Dinner> FindUpcomingDinners()
        {
            return from dinner in _NerdDinnerEntity.Dinners
                   where dinner.EventDate > DateTime.Now
                   orderby dinner.EventDate
                   select dinner;
        }

        // Query Method
        public Dinner GetDinner(int id)
        {
            return _NerdDinnerEntity.Dinners.FirstOrDefault(d => d.DinnerID == id);

        }

        // Insert Method
        public void Add(Dinner dinner)
        {
            _NerdDinnerEntity.Dinners.AddObject(dinner);
        }

        // Delete Method
        public void Delete(Dinner dinner)
        {
            foreach (var rsvp in dinner.RSVPs)
            {
                _NerdDinnerEntity.RSVPs.DeleteObject(rsvp);
            }

            _NerdDinnerEntity.Dinners.DeleteObject(dinner);
        }

        // Persistence Method
        public void Save()
        {
            _NerdDinnerEntity.SaveChanges();
        }
    }

代码 C:

        // **************************************
        // GET: /Dinners/Create/
        // **************************************
        public ActionResult Create()
        {
            Dinner dinner = new Dinner() { EventDate = DateTime.Now.AddDays(7) };
            return View(dinner);
        }

        // **************************************
        // POST: /Dinners/Create/
        // **************************************
        [HttpPost]
        public ActionResult Create(Dinner dinner) {
            if (ModelState.IsValid) 
            {               
                dinner.HostedBy = "The Code Dude";
                _dinnerRepository.Add(dinner);
                _dinnerRepository.Save();
                return RedirectToAction("Details", new { id = dinner.DinnerID });
            }
            else
            {
                return View(dinner);   
            }
        }

代码 D:

        // **************************************
        // GET: /Dinners/Edit/{id}
        // **************************************
        public ActionResult Edit(int id)
        {
            Dinner dinner = _dinnerRepository.GetDinner(id);
            return View(dinner);
        }

        // **************************************
        // POST: /Dinners/Edit/{id}
        // **************************************
        [HttpPost]
        public ActionResult Edit(int id, FormCollection formValues)
        {
            Dinner dinner = _dinnerRepository.GetDinner(id);
            if (TryUpdateModel(dinner)){
                _dinnerRepository.Save();
                return RedirectToAction("Details", new { id=dinner.DinnerID });
            }
            return View(dinner);
        }

I已向 Wrox 和其中一位作者发送帮助请求,但尚未收到任何人的回复。由于这些错误,本书的读者甚至无法继续完成第一章的其余部分。即使我从 Codeplex 下载最新版本,它仍然存在相同的错误。有人可以帮助我并告诉我需要修复什么吗?谢谢-艾德。

Platform: Windows 7 Ultimate
IDE: Visual Studio 2010 Ultimate
Web Environment: ASP.NET MVC 2
Database: SQL Server 2008 R2 Express
Data Access: Entity Framework 4
Form Validation: DataAnnotations
Sample App: NerdDinner from Wrox Pro ASP.NET MVC 2
Book: Wrox Professional MVC 2
Problem with Chapter 1 - Section: "Integrating Validation and Business Rule Logic with Model Classes" (pages 33 to 35)

ERROR Synopsis: NerdDinner form validation ERROR with DataAnnotations and db nulls.

DataAnnotations in sample code does not work when the database fields are set to not allow nulls.

ERROR occurs with the code from the book and with the sample code downloaded from codeplex.

Help! I'm really frustrated by this!! I can't believe something so simple just doesn't work???

Steps to reproduce ERROR:

  1. Set Database fields to not allow NULLs (See Picture)
  2. Set NerdDinnerEntityModel Dinner class fields'
    Nullable property to false (See Picture)
  3. Add DataAnnotations for Dinner_Validation class (CODE A)
  4. Create Dinner repository class (CODE B)
  5. Add CREATE action to DinnerController (CODE C)
  6. This is blank form before posting (See Picture)
  7. This null ERROR occurs when posting a
    blank form which should be
    intercepted by the Dinner_Validation class
    DataAnnotations. Note ERROR message
    says that "This property cannot be
    set to a null value. WTH???
    (See Picture)
  8. The next ERROR occurs during the edit
    process. Here is the Edit controller
    action (CODE D)
  9. This is the "Edit" form with intentionally wrong
    input to test Dinner Validation
    DataAnnotations (See Picture)
  10. The ERROR occurs again when posting the
    edit form with blank form fields. The post request
    should be intercepted by the Dinner_Validation class DataAnnotations. Same
    null entry error. WTH??? (See Picture)

See screen shots at:

http://www.intermedia4web.com/temp/nerdDinner/StackOverflowNerdDinnerQuestionshort.png

CODE A:

    [MetadataType(typeof(Dinner_Validation))]
    public partial class Dinner { }

    [Bind(Include = "Title, EventDate, Description, Address, Country, ContactPhone, Latitude, Longitude")] 
    public class Dinner_Validation
    {
        [Required(ErrorMessage = "Title is required")]
        [StringLength(50, ErrorMessage = "Title may not be longer than 50 characters")]
        public string Title { get; set; }

        [Required(ErrorMessage = "Description is required")]
        [StringLength(265, ErrorMessage = "Description must be 256 characters or less")]
        public string Description { get; set; }

        [Required(ErrorMessage="Event date is required")]
        public DateTime EventDate { get; set; }

        [Required(ErrorMessage = "Address is required")]
        public string Address { get; set; }

        [Required(ErrorMessage = "Country is required")]
        public string Country { get; set; }

        [Required(ErrorMessage = "Contact phone is required")]
        public string ContactPhone { get; set; }

        [Required(ErrorMessage = "Latitude is required")]
        public double Latitude { get; set; }

        [Required(ErrorMessage = "Longitude is required")]
        public double Longitude { get; set; }
    }

CODE B:

    public class DinnerRepository
    {
        private NerdDinnerEntities _NerdDinnerEntity = new NerdDinnerEntities();

        // Query Method
        public IQueryable<Dinner> FindAllDinners()
        {
            return _NerdDinnerEntity.Dinners;
        }

        // Query Method
        public IQueryable<Dinner> FindUpcomingDinners()
        {
            return from dinner in _NerdDinnerEntity.Dinners
                   where dinner.EventDate > DateTime.Now
                   orderby dinner.EventDate
                   select dinner;
        }

        // Query Method
        public Dinner GetDinner(int id)
        {
            return _NerdDinnerEntity.Dinners.FirstOrDefault(d => d.DinnerID == id);

        }

        // Insert Method
        public void Add(Dinner dinner)
        {
            _NerdDinnerEntity.Dinners.AddObject(dinner);
        }

        // Delete Method
        public void Delete(Dinner dinner)
        {
            foreach (var rsvp in dinner.RSVPs)
            {
                _NerdDinnerEntity.RSVPs.DeleteObject(rsvp);
            }

            _NerdDinnerEntity.Dinners.DeleteObject(dinner);
        }

        // Persistence Method
        public void Save()
        {
            _NerdDinnerEntity.SaveChanges();
        }
    }

CODE C:

        // **************************************
        // GET: /Dinners/Create/
        // **************************************
        public ActionResult Create()
        {
            Dinner dinner = new Dinner() { EventDate = DateTime.Now.AddDays(7) };
            return View(dinner);
        }

        // **************************************
        // POST: /Dinners/Create/
        // **************************************
        [HttpPost]
        public ActionResult Create(Dinner dinner) {
            if (ModelState.IsValid) 
            {               
                dinner.HostedBy = "The Code Dude";
                _dinnerRepository.Add(dinner);
                _dinnerRepository.Save();
                return RedirectToAction("Details", new { id = dinner.DinnerID });
            }
            else
            {
                return View(dinner);   
            }
        }

CODE D:

        // **************************************
        // GET: /Dinners/Edit/{id}
        // **************************************
        public ActionResult Edit(int id)
        {
            Dinner dinner = _dinnerRepository.GetDinner(id);
            return View(dinner);
        }

        // **************************************
        // POST: /Dinners/Edit/{id}
        // **************************************
        [HttpPost]
        public ActionResult Edit(int id, FormCollection formValues)
        {
            Dinner dinner = _dinnerRepository.GetDinner(id);
            if (TryUpdateModel(dinner)){
                _dinnerRepository.Save();
                return RedirectToAction("Details", new { id=dinner.DinnerID });
            }
            return View(dinner);
        }

I have sent Wrox and one of the authors a request for help but have not heard back from anyone. Readers of the book cannot even continue to finish the rest of chapter 1 because of these errors. Even if I download the latest build from Codeplex, it still has the same errors. Can someone please help me and tell me what needs to be fixed? Thanks - Ed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深爱成瘾 2024-09-21 06:17:18

终于找到这本书的Wrox论坛有答案了。答案其实是令人惊讶的。它与 Visual Studio 2010 中的调试器有关。

基本上只需按 F5 即可继续,一切正常。

以下是包含更多答案的论坛主题的链接:
http: //p2p.wrox.com/book-professional-asp-net-mvc-2/79788-constraintexception-unhandled-user-code.html#post259245

Finally found the Wrox forum for this book that has the answer. The answer is actually surprising. It has something to do with the debugger in Visual Studio 2010.

Essentially just hit F5 to continue and everything works fine.

Here is the link to the forum thread with more answers:
http://p2p.wrox.com/book-professional-asp-net-mvc-2/79788-constraintexception-unhandled-user-code.html#post259245

倾城月光淡如水﹏ 2024-09-21 06:17:18

工具->选项-> (展开)调试-> (常规)启用异常助手。

Visual Studio 只是想提供帮助! :) 一开始也吓到了我......以为代码有一些令人震惊的错误。是的,只要恢复执行,一切都会好起来的。验证内部将捕获异常(以及其他异常,例如转换、范围等)并将其记录在 ModelState.Errors 集合中。

Tools -> Options -> (expand) Debugging -> (General) Enable the exception assistant.

It's just Visual Studio trying to be helpful! :) Scared me too at first ... thought there was something show-stoppingly wrong with the code. Yeap, just resume execution and all will be fine. The validation internals will catch the Exception (this and others as well, such as conversion, range, etc) and log it in the ModelState.Errors collection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文