ここで深刻なn00b警告。憐れんでください!
これで、Nerd Dinner MVCチュートリアルを終了し、 NerdDinnerプログラムを一種の大まかなテンプレートとして使用してVB.NETアプリケーションをASP.NETMVCに変換しているところです。
「IsValid/GetRuleViolations()」パターンを使用して、ビジネスルールに違反する無効なユーザー入力または値を識別しています。LINQ to SQLを使用しており、CustomerRepositoryクラスを介してデータベースへの変更を保存しようとすると、検証を実行してアプリケーション例外をスローできる「OnValidate()」フックを利用しています。
とにかく、フォームの値が検証メソッドに到達するまでに、無効な型がすでにデフォルト値または既存の値に変換されていることを除いて、すべてがうまく機能します。(私は整数の「StreetNumber」プロパティを持っていますが、これはDateTimeやその他の非文字列でも問題になると思います。)
ここで、Html.ValidationMessageがStreetNumberフィールドの横に表示されているため、UpdateModel()メソッドが例外をスローし、値を変更していると推測していますが、検証メソッドは元の入力を認識しません。これには2つの問題があります。
Html.ValidationMessageは何かが間違っていることを通知しますが、Html.ValidationSummaryに対応するエントリがありません。無効なキャストまたは何もないよりも良い何かを示す例外メッセージをそこに表示することさえできれば。
Customer部分クラスにある検証メソッドは、元のユーザー入力を認識しないため、問題がエントリの欠落なのか無効なタイプなのかわかりません。検証ロジックを1つの場所で適切に維持し、フォーム値にアクセスする方法がわかりません。
もちろん、ユーザー入力を処理するロジックをビューに書き込むこともできますが、それはMVCで行うべきこととは正反対のようです。
新しい検証パターンが必要ですか、それとも元のフォーム値をモデルクラスに渡して処理する方法はありますか?
CustomerControllerコード
// POST: /Customers/Edit/[id]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues)
{
Customer customer = customerRepository.GetCustomer(id);
try
{
UpdateModel(customer);
customerRepository.Save();
return RedirectToAction("Details", new { id = customer.AccountID });
}
catch
{
foreach (var issue in customer.GetRuleViolations())
ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
return View(customer);
}