6

私は2つのアクションを持つコントローラを持っています:

[AcceptVerbs("GET")]
    public ActionResult Add()
    {
        PrepareViewDataForAddAction();
        return View();
    }


[AcceptVerbs("POST")]
    public ActionResult Add([GigBinderAttribute]Gig gig, FormCollection formCollection)
    {
        if (ViewData.ModelState.IsValid)
        {
            GigManager.Save(gig);
            return RedirectToAction("Index", gig.ID);
        }
        PrepareViewDataForAddAction();
        return View(gig);
    }

ご覧のとおり、フォームがデータを投稿するとき、Add アクションは GigBinder (IModelBinder の実装) を使用します。

このバインダーには次のものがあります。

 if (int.TryParse(bindingContext.HttpContext.Request.Form["StartDate.Hour"], out hour))
        {
           gig.StartDate.Hour = hour;
        }
        else
        {
            bindingContext.ModelState.AddModelError("Doors", "You need to tell us when the doors open");
        }

フォームには、id "StartDate.Hour" のテキスト ボックスが含まれています。

上記のように、GigBinder は、ユーザーが ID "StartDate.Hour" のテキスト ボックスに整数を入力したことを確認するためにテストします。そうでない場合は、AddModelError を使用してモデル エラーがモデル状態に追加されます。

gigs プロパティの gigs.StartDate.Hour は厳密に型指定されているため、ユーザーがフォームのテキスト ボックスにこれを入力した場合、その値をたとえば「TEST」に設定することはできません。

したがって、ユーザーが整数ではなく文字列を入力したため、gigs.StartDate.Hour の値を設定できません。

モデル状態が無効な場合、追加ア​​クションはビューを返し、モデルを渡す (return View(gig);) ため、フォームが検証メッセージで再表示されると、値「TEST」がテキストボックスに表示されません。代わりに、gig.StartDate.Hour のデフォルト値になります。

この問題を回避するにはどうすればよいですか? 本当にくっついた!

4

3 に答える 3

2

問題は、ViewModel が View と十分に一致していないことだと思います。MVC では、ViewModel が View と可能な限り一致することが非常に重要です。

ViewModel では整数を想定していますが、View では TextBox を使用してプロパティをレンダリングしているため、あらゆる種類のテキストが許可されます。ここには不一致があり、それらをマッピングしようとして経験している問題は、不一致の兆候です。

次のいずれかを行う必要があると思います:
1. ViewModel プロパティのタイプを文字列に変更し、コントローラーで検証を行って、入力された文字列が実際に数値であることを確認するか、または:
2. ビューがレンダリングするコントロールを、カスタムコントロールまたはJavascript検証を介して数値を入力できるようにします(@Qun Wangが推奨するように)

個人的には、オプション 1 をお勧めします。そうすれば、ViewModel は View の実装に依存しません。

于 2010-04-29T02:04:50.747 に答える
1

最初に、基本的なクライアント側の検証を行う必要があると思います。サーバーへの投稿を許可しないでください。

于 2010-04-10T09:27:08.287 に答える