【问题标题】:ASP.Net MVC dropdown list data missing from model on POSTPOST 模型中缺少 ASP.Net MVC 下拉列表数据
【发布时间】:2019-09-12 00:33:22
【问题描述】:

我将一个下拉列表作为我的视图模型的一部分传递给创建视图。

视图模型:

public class VendorVM
{
    public Entities.Vendor Vendor { get; set; }

    public SelectList VendorParentList { get; set; }
    public string VendorParentSelected { get; set; }
}

查看:

@Html.DropDownListFor(x => Model.VendorParentSelected, new SelectList(Model.VendorParentList, "Value", "Text"), "-- Select --", htmlAttributes: new { @class = "form-control", id = "ddVendorParent" })

控制器:

[HttpGet]
public ActionResult Create()
{
    VendorVM theVendorVM = new VendorVM();
    theVendorVM.Vendor = new Entities.Vendor();

    List<Entities.Vendor> theVendorList = BLL.GetData.RetrieveVendorParents();
    theVendorVM.VendorParentList = new SelectList(theVendorList, "ID", "Name");

    return View(theVendorVM);
}

[HttpPost]
public ActionResult Create(VendorVM theVendorVM)
{
    try
    {
        Entities.Vendor theVendor = new Entities.Vendor();
        Entities.Vendor theVendorParent = new Entities.Vendor();

        if (theVendorVM.VendorParentSelected != null)
        { theVendorParent.ID = Convert.ToInt32(theVendorVM.VendorParentSelected); }
        theVendorVM.Vendor.VendorParent = theVendorParent;

        // Store the Vendor 
        theVendor = BLL.StoreData.InsertVendor(theVendorVM.Vendor);

        theVendor.Errors.Add("Holy Cannoli!!!");

        if (theVendor.HasErrors)
        {
            foreach (String err in theVendor.Errors)
            {
                ModelState.AddModelError(string.Empty, err);
            }
            return View(theVendorVM);
        }
        else { return RedirectToAction("Index"); }
    }
    catch (Exception ex)
    {
        return View();
    }
} 

当我从视图中返回 POST 时,VendorParentList == NULL。

我在这里用“Holy Cannoli”伪造服务器端错误。我希望能够保持 ViewModel 状态并重新显示出现错误的视图。

为什么 ViewModel.VendorParentList 为空? Vendor 对象包含正确的值。我发送给 View 的 Viewmodel 中的任何 List 都会以 null 的形式返回到 POST。

我该如何解决这个问题。或者,更好的是,我做错了什么?

【问题讨论】:

  • 这就是在表单中发布的方式。仅发布表单控件(输入、ddls、隐藏字段、文本区域等)。不是整个视图模型。为什么不在帖子中再次从数据库中获取您的视图模型或列表?
  • 这就是我现在正在做的事情。不得不再次从数据库请求或构建会话变量以进行缓存似乎非常浪费。你提到了 dd,但是它们没有被退回——这就是问题所在。我必须捕获所做的选择,但没有发布整个 dd。
  • ddls 是指下拉列表中的选定值。不是整个下拉列表。来自网络表单,您可能会觉得这很奇怪,但仅发布所需的信息可以最大限度地减少传输到服务器的数据。如果您确实需要发布选择列表,请使用 for 循环和表单内的 vendorlist 项的隐藏字段。

标签: asp.net-mvc razor model-view-controller


【解决方案1】:

哦,我想我明白了。您希望在出现错误时填充下拉列表。当您发布表单时,下拉列表不会与 ViewModel 一起发布,而只会与选定的 ID 一起发布。如果出现错误,您将不得不重新填充(重新创建)保存菜单的 ViewBag(或者在您的情况下为 View-model 属性),以便再次加载它。所以就在return View(theVendorVM); 行之前,你应该添加

List<Entities.Vendor> theVendorList = BLL.GetData.RetrieveVendorParents();
theVendorVM.VendorParentList = new SelectList(theVendorList, "ID", "Name");

这样,在 View 与模型一起返回之前,该属性与菜单一起加载。

【讨论】:

  • 谢谢,这正是我正在做的。我只是认为当我真正想做的所有事情都重新显示页面以允许更正错误时,必须为此返回数据库或缓存版本是愚蠢的。我怀疑我只是被 webform 世界中的 ViewState 宠坏了。我希望这是我的缺点,而不是 MVC 框架。显然,我是唯一一个对此抱怨的人。
【解决方案2】:

它为 null 的原因是因为页面上有一个 html 表单,并且该表单只会回传其上的表单值。 IE。不包括 VendorParentList 的值,因为它们不在表单上。

你不一定做错了什么。正如 cmets 中提到的,很多时候发回这些信息会浪费资源。这是一个很好的情况,因为你有机会改变行为 以满足您的应用程序的需求。

如果对于您的应用程序,您认为这是一个问题,并且您想发回这些值以避免在 post 时建立数据库连接,那么正如 imAbhi 所说,您可以使用隐藏字段。以下是它的工作原理。

将您的视图模型更改为

public class VendorVM
{
    public Entities.Vendor Vendor { get; set; }

    public IList<Parent> VendorParentList { get; set; }  //Ilist instead of SelectList 
    public string VendorParentSelected { get; set; }
}

将您的视图更改为此,注意我是如何将“Id”和“Name”传递到此处的选择列表而不是控制器中的。

@using (Html.BeginForm())
{
    @Html.DropDownListFor(x => Model.VendorParentSelected, new SelectList(Model.VendorParentList, "Id", "Name"), "-- Select --", htmlAttributes: new { @class = "form-control", id = "ddVendorParent" })

    for (int i = 0; i < Model.VendorParentList.Count; i++)
    {
        <input type="hidden" name="VendorParentList[@i].Id" value="@Model.VendorParentList[i].Id" />
        <input type="hidden" name="VendorParentList[@i].Name" value="@Model.VendorParentList[i].Name" />
    }
    <input type="submit" value="submit">
}

我假设你的 Parent 类看起来像这样

public class Parent
{
    public int Id { get; set; }
    public string Name { get; set; }
    //other fields
}

现在在回发时,您会发现您的 VendorParentList 将填充值。

【讨论】:

  • 谢谢戴夫。我看你是怎么处理这个的。我的问题是“假定”在 Posted back 表单中的内容以及不存在的内容。 VendorParentList 是模型的一部分,表单 - 不随 POST 发回 VendorParentSelected 是模型的一部分,表单 - 随 POST 发回由控制器决定使用或忽略它。我意识到我正在与市政厅作战,这显然是一个逻辑练习。赞成
猜你喜欢
  • 1970-01-01
  • 2013-09-07
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 2012-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多