【问题标题】:How to post the selected value of a selectlist to the controller using a view model?如何使用视图模型将选择列表的选定值发布到控制器?
【发布时间】:2011-02-09 21:38:12
【问题描述】:

已经以各种形式提出了这个问题,但似乎没有一个答案适合我的情况。我只是想在我的控制器中检索下拉列表的选定值。

这是我的代码:

ViewModel.cs

public class ViewModel
{
  public ViewModel() {}
  public ViewModel(Contact contact, IEnumerable<State> states)
    {
      this.Contact = contact;
      this.States = new SelectList(states, "Id", "Name", contact.StateId);
    }
  public Contact Contact {get;set;}
  public SelectList States {get;set;}
}

Controller.cs

[HttpPost]
public ActionResult Edit(ViewModel viewModel)
{
  _contactService.UpdateContact(viewModel.Contact);
  return RedirectToAction("Item", new {id = viewModel.Contact.Id});
}

View.cshtml

<button type="submit" onclick="javascript:document.update.submit()"><span>Update</span></button>//aesthic usage. 
@{using (Html.BeginForm("Edit", "Controller", FormMethod.Post, new { name = "update" }))
  {
   @Html.HiddenFor(m => m.Contact.Id)
   @Html.LabelFor(m => m.Contact.Name, "Name:")
   @Html.TextBoxFor(m => m.Contact.Name)

   <label for="state">State:</label>
   @Html.DropDownList("state", Model.States)
}
}

除了下拉列表中的任何值都没有在我发布的 viewModel 中传递给控制器​​之外,一切都按预期工作。编辑页面和所有字段正确加载。下拉列表正确绑定并正确显示其选择的值。但是,当我发布时,我只会将“联系人”对象传递给控制器​​。 “States” SelectList 对象为空。

我尝试在我的 viewModel 构造函数中映射“StateId”属性,但这也不起作用。我做错了什么?

谢谢。

【问题讨论】:

    标签: drop-down-menu asp.net-mvc-3 controller viewmodel


    【解决方案1】:

    我讨厌回答自己的问题,但根据我遇到的多个问题以及无数可用的答案,我想我会总结一下我的发现。

    首先感谢 Filip,他的回答并没有完全解决我的问题,但它引导我朝着正确的方向前进。 +1

    如果您要创建需要下拉列表的查看和编辑表单,这里有一些建议和注意事项。我将从满足我需要的参数列表开始。

    1. 在我看来,强类型视图更可取。尽量减少魔术字符串。
    2. 视图模型应包含尽可能少的逻辑和无关元素。唯一的工作应该是促进数据对象的收集。
    3. 下拉列表应显示所选值。
    4. 所选值应轻松映射回表单提交时的视图模型。

    这听起来像是一个显而易见且容易获得的列表,但对于刚接触 MVC 的人来说,它不是。我将使用 cmets 从上面修改我的代码。这就是我所做的。

    ViewModel.cs

    public class ViewModel
    {
      public ViewModel() {}
      public ViewModel(Contact contact, IList<State> states)
      {
    //no need to pass in a SelectList or IEnumerable, just what your service or repository spits out
        this.Contact = contact;
        this.States = states;
      }
      public Contact Contact {get;set;}
      public IList<State> States {get;set;}
    }
    

    Controller.cs //与上面没有什么不同

    public ActionResult Edit(int id)
    {
      var contact = _contactService.GetContactById(id);
      var states = _stateService.GetAllStates();
      return View(new ViewModel(contact, states));
    }
    
    public ActionResult Edit(ViewModel viewModel)
    {
      _contactService.UpdateContact(viewModel.Contact);
      return RedirectToAction("Edit", new {id = viewModel.Contact.Id });
    }
    

    查看//感谢 Artirto post

    @{using (Html.BeginForm("Edit", "Controller", FormMethod.Post))
     {
      @Html.HiddenFor(m => m.Contact.Id)
      @Html.DropDownListFor(m => m.Contact.StateId, new SelectList(Model.States, "Id", "Name", @Model.Contact.StateId))
    <input type="submit" value="Save" />
    }
    }
    

    【讨论】:

    • 您是在选择 dropdownvalue 后单击任何按钮,还是只是在选择要回发的下拉列表时单击?
    • 这是让视图模型具有联系人实体的正确方法吗?
    【解决方案2】:

    尝试改用@Html.DropDownListFor,如果“状态”是模型的一部分,您可以像这样使用它:

    @Html.DropDownListFor(m =&gt; m.Contact.StateId, Model.States, "-- Please select a State --") 其中m.State 保存选定的值。

    也不要将 IEnumerable 与模型混淆,我会将其放在 ViewBag / ViewData 中。

    它看起来像这样:

    @Html.DropDownListFor(m =&gt; m.Contact.StateId, (IEnumerable&lt;string&gt;)ViewBag.States, "-- Please select a State --")

    在您返回此视图的操作中,您需要将可枚举的 State 初始化为 ViewBag.States 属性。

    【讨论】:

    • 我使用了 ViewBag,它按预期工作,但它看起来像是另一个迷你视图模型。为了基于我发布的代码进行论证,当它们是视图模型的一部分时,为什么选择列表会返回 null?
    • 因为在您的模型中您需要SelectList,而这不是表单将发布的内容。如果您在名为“state”的操作上添加string 参数,它应该会获得您选择的值。
    猜你喜欢
    • 2020-07-12
    • 2014-08-22
    • 1970-01-01
    • 2019-10-31
    • 2011-08-10
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多