0

ViewBag 与客户端验证有何关系?

考虑以下示例。我有两个动作方法都命名为测试一个接受获取请求和其他后请求。

get-action 返回一个视图,用户可以在其中编辑选择的值。此选择的值是一个可为空的 int。如果从会话中找到此选择的值,则将其设置为已选择。

post-action 将提交的值添加到 session 并将用户重定向回 get-action。

这段代码的工作方式如下:第一次提交非空值后,应用客户端验证,但前提是我向 ViewBag 添加了一个与 select 具有相同名称的值。所以我的问题是为什么?我真的很想了解为什么它会这样工作。根据我的阅读,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 中,当它们中的两个具有相同的名称/键时,它们会相互覆盖,你会得到一些非常时髦的行为。我不确定您的场景到底是什么问题(通常人们有某种 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 回答