【问题标题】:MVC ViewModel collection null on postback回发时 MVC ViewModel 集合为空
【发布时间】:2015-11-11 14:54:40
【问题描述】:

我有一个 ViewModel,其中包含一个名为 Types 的 SelectListItems 列表。当我进入编辑页面时,类型被填充并且下拉列表包含预期的项目。当我将更改发布回来时,SelectListItems 列表为空。即“model.Types”为空。

为什么会这样,我该如何解决?

我已经看到这个问题被问了几次,但他们都有不同的答案,我尝试了几次,但它们都不起作用。

我是 MVC 新手,所以请帮忙。

谢谢

我的视图模型:

public class StaticItemViewModel
{
    public Static_Item StaticItem { get; set; }
    public List<SelectListItem> Types { get; set; }     
}

我的控制器:

public class StaticItemController : Controller
{
    private DB db = new DB();

    public ActionResult Edit(int id)
    {            
        Static_Item staticItem = db.Static_Item.Find(id);

        if (staticItem == null)
        {
            return HttpNotFound();
        }

        StaticItemViewModel staticItemViewModel = new StaticItemViewModel()
        {
            StaticItem = staticItem,
            Types = LoadStaticItemTypes(staticItem.Type)
        };

        return View(staticItemViewModel);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include="StaticItem")] StaticItemViewModel model)                    
    {
        if (ModelState.IsValid)
        {
            model.StaticItem.Changed_Date = DateTime.Now;
            db.Entry(model.StaticItem).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(model);
    }

    List<SelectListItem> LoadStaticItemTypes(string selectedType = "")
    {
        List<SelectListItem> items = new List<SelectListItem>();

        foreach (var item in db.Static_Item.Select(s => s.Type).Distinct().OrderBy(s => s))
        {
            items.Add(new SelectListItem { Text = item, Value = item, Selected = item == selectedType });
        }

        return items;
    }
}

我的观点:

@model StaticItemViewModel

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm())
    {
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>@Model.StaticItem.Description</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.StaticItem.UN_Static_Item)

        <div class="form-group">
            @Html.LabelFor(model => model.StaticItem.Description, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.StaticItem.Description, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.StaticItem.Description, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.StaticItem.Type, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.StaticItem.Type, Model.Types, new { @class="form-control" })
                @Html.ValidationMessageFor(model => model.StaticItem.Type, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

【问题讨论】:

    标签: asp.net-mvc-5 asp.net-mvc-viewmodel


    【解决方案1】:

    那是因为Types 只是保存选项列表,而实际选项本身永远不会被回发。你需要一个像这样的属性:

    public List<int> SelectedTypes { get; set; }
    

    然后在你的视图中绑定到那个:

    @Html.ListBoxFor(m => m.SelectedTypes, Model.Types)
    

    假设您的选项值只是类型的 PK,您也可以绑定到 List&lt;string&gt; 等,但它必须是原始类型(字符串、整数等)。您不能回发完整的 Type 对象。如果您需要这些,则需要使用 id 列表或其他任何东西从数据库中查找它们。

    【讨论】:

    • 感谢您的回复 您是说 SelectedTypes 集合应该填充到 Edit 页面的 Get 请求中吗? Type 集合在编辑回发时仍将为 Null,所以我是否也必须重新填充它们?
    • 是的。 Types 应该是所有可能的类型,你不需要说明它当前是否被选中; Razor 会解决这个问题。 SelectedTypes 然后应该在返回视图之前使用当前选择的类型(如果有)进行设置。而且,是的,您总是必须重新填充您的选择列表项。发布后它们将始终为空。
    猜你喜欢
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多