0

ViewBag はクライアント側の検証とどのように関連していますか?

次の例を考えてみましょう。私は 2 つのアクション メソッドを持っています。どちらも Test という名前で、1 つは get-requests を受け取り、もう 1 つは post-request です。

get-action は、ユーザーが select の値を編集できるビューを返します。この選択の値は、null 許容の int です。この選択の値がセッションから見つかった場合は、選択済みとして設定されます。

事後アクションは、送信された値をセッションに追加し、ユーザーを get アクションにリダイレクトします。

このコードは次のように機能します。null 以外の値が送信された後の最初の時点で、クライアント側の検証が適用されますが、select と同じ名前の ViewBag に値を追加した場合のみです。だから私の質問はなぜですか?なぜこれが機能するのかを本当に理解したいと思います。私が読んだことから、 ViewBag(ViewDataDictionary) はビューにデータを渡すためにのみ使用され、検証に影響することを読んだことはありません。

[HttpGet]
public ActionResult Test()
{
    int? id = (int?)Session["id"];
    List<SelectListItem> options = new List<SelectListItem>();
    options.Add(new SelectListItem { Selected = 1 == id, Text = "Option 1", Value = "1" });
    options.Add(new SelectListItem { Selected = 2 == id, Text = "Option 2", Value = "2" });
    options.Add(new SelectListItem { Selected = 3 == id, Text = "Option 3", Value = "3" });
    ViewBag.Options = options;
    ViewBag.id = id; //This adds client side validation
    return View();
}

[HttpPost]
public ActionResult Test(int? id)
{
    Session["id"] = id;
    return RedirectToAction("Test");
}

@using (Html.BeginForm("Test", "MyController", FormMethod.Post))
{
    @Html.Label("id", "Select")
    @Html.DropDownList("id", (List<SelectListItem>)ViewBag.Options, "Empty")
    <input type="submit" value="Submit" />
}
4

1 に答える 1

0

ViewBag 変数とモデルのプロパティに同じ名前を付けないでください。最終的にこれらの値はすべて FormCollection に存在し、そのうちの 2 つが同じ名前/キーを持つ場合、それらは互いにオーバーライドし、非常にファンキーな動作が得られます。あなたのシナリオの問題が正確に何であるかはわかりませんが(通常、人々は何らかのViewModelを持っています)、次のシナリオを検討してください:

public class Product
{
   public int ProductId { get; set; }
   public string ProductName { get; set; }
}

これがあなたのモデルであり、コントローラーアクションで次のようなことを行う場合:

public ActionResult EditProduct(int id)
{
   var model = ProductDomainLogic.GetProduct(id);
   ViewBag.ProductName = "Whatever";
   return View(model);
}

同じ名前の 2 つの要素があり、FormCollection で互いに上書きされるため、深刻な頭痛の種になりました。要約すると、常にモデルで使用されていない名前で ViewBag 変数に名前を付けます。

于 2013-06-18T15:25:50.423 に答える