【问题标题】:MVC: POST controller method get empty DictionaryMVC:POST控制器方法获取空字典
【发布时间】:2017-02-17 15:15:41
【问题描述】:

我的控制器构造并填充模型的GET方法,其中包括Dictionary<int, MyClass>,并将其传输到View。但之后,POST 控制器方法得到非空模型和空字典。

型号:

  public class CheckBoxItem
  {
    public string Name { get; set; }
    public double Data { get; set; }
    public bool Selected { get; set; }
  }
  public class CreateNewEventModel
  {
    [Required(ErrorMessage = "Error text")]
    [Display(Name = "Header name")]
    public string EventName { get; set; }
    public Dictionary<int, CheckBoxItem> CheckBoxDataItems { get; set; }
    public CreateNewEventModel()
    {
      CheckBoxDataItems = new Dictionary<int, CheckBoxItem>();
    }
  }

控制器:

public ActionResult CreateEvent()
    {
      CreateNewEventModel model = new CreateNewEventModel();
      // FILL MODEL
      foreach (var user in db.UsersInfo.ToList())
      {
        model.CheckBoxDataItems.Add(user.Id, new CheckBoxItem()
        {
          Name = user.Name,
          Data = 0,
          Selected = false
        });
      }
      // THERE IS FULL MODEL
      return View(model);
    }
    [HttpPost]
    public ActionResult CreateEvent(CreateNewEventModel model)
    {
      // THERE IS model.Event name include text
      // BUT model.CheckBoxDataItems is empty
      if (ModelState.IsValid)
      {
        ...    
        return View(model);
      }
      return View(model);
    }

查看:

@model HLyaa.Models.CreateNewEventModel

@{
    ViewBag.Title = "Create Event";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Создание события</h2>

@if (Model.CheckBoxDataItems.Count() != 0)
{
  using (Html.BeginForm("CreateEvent", "Events", FormMethod.Post))
  {
    @Html.ValidationSummary()
    <div>
      @Html.LabelFor(model => model.EventName)
      <div>
        @Html.EditorFor(model => model.EventName)
      </div>
    </div>
    <table>
      @foreach (var kvpair in Model.CheckBoxDataItems)
      {
        <tr>
          <td>
            @Html.CheckBoxFor(model => model.CheckBoxDataItems[kvpair.Key].Selected)
          </td>
          <td>
            @Html.DisplayFor(model => model.CheckBoxDataItems[kvpair.Key].Name)
            @Html.HiddenFor(model => model.CheckBoxDataItems[kvpair.Key].Selected)            
            @Html.HiddenFor(model => model.CheckBoxDataItems[kvpair.Key].Name)         
          </td>
          <td>
            @Html.TextBoxFor(model => model.CheckBoxDataItems[kvpair.Key].Data, new { @type = "number" })
          </td>
        </tr>
      }
    </table>
    <br />
    <input type="submit" value="Next" />
  }
}

如何将字典中的数据从视图传输到控制器?

【问题讨论】:

    标签: c# asp.net-mvc dictionary asp.net-mvc-5


    【解决方案1】:

    正如我在this post 中回答的那样,您需要在访问字典的键和值之前调用字典上的“ToArray()[*]”,这样您就可以指定 ASP 模型绑定器用来发送数据的索引到控制器。 ;)

    【讨论】:

      【解决方案2】:

      字典没有,列表/数组是的,但你必须做一些修改。

      修改模型

      public class CheckBoxItem {
          public int UserId { get; set; }
          public string Name { get; set; }
          public double Data { get; set; }
          public bool Selected { get; set; }
      }
      
      public class CreateNewEventModel {
          [Required(ErrorMessage = "Error text")]
          [Display(Name = "Header name")]
          public string EventName { get; set; }
          public List<CheckBoxItem> CheckBoxDataItems { get; set; }
          public CreateNewEventModel() {
              CheckBoxDataItems = new List<CheckBoxItem>();
          }
      }
      

      修改GET方法CreateEvent

      public ActionResult CreateEvent() {
          var model = new CreateNewEventModel();
          //...FILL MODEL
          foreach (var user in db.UsersInfo.ToList()) {
              model.CheckBoxDataItems.Add(new CheckBoxItem() {
                  UserId = user.Id,
                  Name = user.Name,
                  Data = 0,
                  Selected = false
              });
          }
          // THERE IS FULL MODEL
          return View(model);
      }
      

      更新视图

      <table>
        @for (var i = 0; i < Model.CheckBoxDataItems.Count; i++) {
          <tr>
            <td>
              @Html.CheckBoxFor(model => model.CheckBoxDataItems[i].Selected)
            </td>
            <td>
              @Html.DisplayFor(model => model.CheckBoxDataItems[i].Name)
              @Html.HiddenFor(model => model.CheckBoxDataItems[i].UserId)
              @Html.HiddenFor(model => model.CheckBoxDataItems[i].Selected)
              @Html.HiddenFor(model => model.CheckBoxDataItems[i].Name)
            </td>
            <td>
              @Html.TextBoxFor(model => model.CheckBoxDataItems[i].Data, new { @type = "number" })
            </td>
          </tr>
        }
      </table>
      

      CheckBoxDataItems 现在应该在您将其发布到控制器时填充

      【讨论】:

      • 是的。你说的对!它真的有效。但是,我不明白为什么 Dictionary 是空的,但 List 不是。请您解释一下我可以在 Model 中使用哪些类型?
      • 这与您在视图中引用模型属性的方式有关。当您使用foreach 时,视图不会为列表生成一个html,该列表在发布时将转换回列表。当引用像 model.CheckBoxDataItems[i].Name 这样的索引时,视图将生成像 name="CheckBoxDataItems[0].Name" 这样的名称,它会在发布时正确转换回列表。
      • 框架试图解释发送的表单数据并将它们转换为强类型对象。
      • 查看这篇文章。 hanselman.com/blog/…
      • 感谢您的帮助
      猜你喜欢
      • 1970-01-01
      • 2013-08-05
      • 2012-06-25
      • 2017-12-10
      • 2017-12-02
      • 2013-05-02
      • 2019-06-27
      • 2014-12-15
      • 1970-01-01
      相关资源
      最近更新 更多