2

プラットフォーム: Windows 7 Ultimate
IDE: Visual Studio 2010 Ultimate
Web 環境: ASP.NET MVC 2
データベース: SQL Server 2008 R2 Express
データ アクセス: Entity Framework 4
フォーム検証: DataAnnotations
サンプル アプリ: NerdDinner from Wrox Pro ASP.NET MVC 2
Book: Wrox Professional MVC 2
の第 1 章に関する問題 - セクション: 「検証とビジネス ルール ロジックをモデル クラスと統合する」(33 ~ 35 ページ)

ERROR 概要: DataAnnotations と db null を使用した NerdDinner フォーム検証エラー。

データベース フィールドが null を許可しないように設定されている場合、サンプル コードの DataAnnotations は機能しません。

書籍のコードと codeplex からダウンロードしたサンプル コードでエラーが発生します。

ヘルプ!これには本当にイライラします!! こんなに単純なことがうまくいかないなんて信じられない???

エラーを再現する手順:

  1. NULL を許可しないようにデータベース フィールドを設定します(図を参照) 。
  2. NerdDinnerEntityModel ディナー クラス フィールドの Nullable プロパティを false に設定します(図を参照) 。
  3. Dinner_Validation クラスの DataAnnotations を追加(コード A)
  4. Dinner リポジトリ クラスを作成する(コード B)
  5. DinnerController に CREATE アクションを追加する(コード C)
  6. これは投稿前の空白のフォームです(写真を参照)
  7. この null エラーは、Dinner_Validation クラスの DataAnnotations によってインターセプトされる空白のフォームを投稿するときに発生します。「このプロパティは null 値に設定できません。WTH ??? (図を参照) 」というエラー メッセージに注意してください。
  8. 次の ERROR は、編集プロセス中に発生します。コントローラーの編集アクション(コード D)は次のとおりです。
  9. これは、Dinner Validation 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);
        }

Wrox と著者の 1 人に助けを求めるリクエストを送信しましたが、誰からも返事がありません。この本の読者は、これらのエラーのために、第 1 章の残りの部分を読み進めることさえできません。Codeplex から最新のビルドをダウンロードしても、同じエラーが発生します。誰かが私を助けて、何を修正する必要があるか教えてもらえますか? ありがとう - エド。

4

2 に答える 2

2

ツール -> オプション -> (展開) デバッグ -> (全般) 例外アシスタントを有効にします。

Visual Studio が役に立ちたいと思っているだけです。:) 最初は私も怖かった...コードに目を見張るような何かが間違っていると思った。はい、実行を再開するだけで問題ありません。検証の内部は、例外 (これと、変換、範囲などの他のもの) をキャッチし、それを ModelState.Errors コレクションに記録します。

于 2010-12-23T16:52:14.633 に答える
2

最後に、答えがあるこの本の Wrox フォーラムを見つけました。その答えは実に驚くべきものです。Visual Studio 2010 のデバッガーと関係があります。

基本的に F5 を押して続行すると、すべて正常に動作します。

より多くの回答が記載されたフォーラム スレッドへのリンクは次のとおりです

于 2010-08-15T01:35:13.810 に答える