【问题标题】:MVC: Post array of values to controllerMVC:将值数组发布到控制器
【发布时间】:2009-09-02 22:41:35
【问题描述】:

我有一个 asp.net MVC 网站。其中一个页面允许用户向页面动态添加下拉列表,即用户输入 5,这将返回到服务器,在该视图中我创建了 5 个下拉列表。

然后我希望能够在每个回帖中将下拉列表的所有值发送回控制器,并保持它们在数组中的位置。我发现只有更改的值被发回,我无法确定哪个值发生了更改

??什么,你可能会问。这是一个例子:

  1. 该页面允许用户输入 他们家的规格。第一的 他们从下拉列表中选择, drpRooms,房间的数量 他们的房子(假设用户 输入 5)。

  2. 这会发回服务器和 视图用 5 个额外的 drop 渲染回来 向下列表,drpRoom0,drpRoom1, drpRoom2 ... drpRoom4,每滴 下拉列表允许他们选择 其中的家具数量 房间,一个介于 1 到 10 之间的数字。

  3. 用户选择以下 每个下拉菜单的值

    drpRoom0: 2
    drpRoom1:4
    drpRoom2:1
    drpRoom3:8
    drpRoom4: 9

  4. 当用户单击“继续”并 发回表格,我得到了 控制器作为一个数组,即一个数组类型 int : int[] 的值为 {2, 4, 1, 8, 9}。到这里我还好,我可以将下拉列表作为一个 int 数组发回(我通过为每个下拉列表使用相同的名称,但唯一的 ID 来做到这一点)

  5. 这会做一些处理等等 向前。视图被渲染回来 给用户,他们可以改变一个 价值,说他们改变了价值 drpRoom3 的值为 2,当用户 点击继续,我回来了 服务器是一个有 1 个值的数组 在索引 0。因此我无法 确定哪个下拉列表是 改变了。

我知道我可以用 Json 做到这一点,但是我正在寻找独立于 Javascript 的方式来做到这一点

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    您可以使用 MVC SelectList 对象来生成 DropDownList 控件,并使用 Model/ViewModel 模式来将更改持久保存在系统中。

    首先,创建用于将数据传递给视图的 ViewModel 类:

    public class RoomDetailsViewModel
    {
        private int _numberOfRooms;
        public int NumberOfRooms
        {
            get { return _numberOfRooms; }
            set
            {
                _numberOfRooms = value;
    
                RoomDetails = new List<SelectList>(_numberOfRooms);
                for(int i = 0; i < _numberOfRooms; i++)
                    RoomDetails.Add(new SelectList(AllowedRoomValues));
            }
        }
        public List<SelectList> RoomDetails { get; set; }
    
        public RoomDetailsViewModel(RoomDetailsModel model)
        {
            // Get useful info from dataModel
            NumberOfRooms = model.NumberOfRooms;
        }
    
        public static int[] AllowedRoomValues = new [] {0, 1, 2, 3, 4, 5, 6,7,8,9,10};
    }
    

    注意使用 SelectList 的 List。这些将用于生成您需要的 DropDownList。您可以通过提供值列表来限制 SelectList 的选项(请参阅 AllowedRoomValues)。

    接下来,在编辑视图中,使用 Html 帮助器来生成下拉列表:

    <% using (Html.BeginForm()) {%>
    
        <fieldset>
            <legend>Fields</legend>
            <p>
                <label for="NumberOfRooms">NumberOfRooms:</label>
                <%= Html.TextBox("NumberOfRooms", Model.NumberOfRooms) %>
                <%= Html.ValidationMessage("NumberOfRooms", "*") %>
            </p>
    
            <% for(int i = 0; i < Model.NumberOfRooms; i++)
               { %>
                    <%= Html.DropDownList("drpRoom" + i,Model.RoomDetails[i]) %>
            <% } %>
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>
    
    <% } %>
    

    如您所见,您必须确保 RoomDetails 属性永远不会为空,否则您将抛出 NullRef 异常。最好的方法是通过构造函数和设置器,我在 ViewModel 中做到了。

    最后,您需要在控制器的 POST Edit 操作中更新模型:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, FormCollection collection)
    {
        // Grab the actual data model from your ORM repository of choice here
        RoomDetailsModel dataModel = roomDetailRepository.GetItem(r => r.HouseID == id);
    
        try
        {
            // Updating the model/
            for (int i = 0; i < model.NumberOfRooms; i++) // iterate over actual room count
                dataModel.RoomDetails[i] = int.Parse(collection["drpRoom" + i]);
    
            // Generate a ViewModel from your actual DataModel in order to display.
            RoomDetailsViewModel viewModel = new RoomDetailsViewModel(dataModel);
    
            // display back the view using the viewModel.
            return View(viewModel);
        }
        catch
        {
            // error handling...
            return View();
        }
    }
    

    为了简洁起见,我省略了所有数据验证的内容,你懂的!哦!

    【讨论】:

      猜你喜欢
      • 2012-11-26
      • 2017-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-17
      • 2016-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多