【问题标题】:Create List<T> from View and POST with form to MVC controller [duplicate]从 View 和 POST 创建 List<T> 到 MVC 控制器 [重复]
【发布时间】:2016-10-23 16:21:32
【问题描述】:

背景
我正在开发客户的网站项目,我使用 MVC 创建网站。我让 EF 使用 SQLDB 来存储数据。

我的 WebApp 配备了用于管理/添加/更新Items 等的后台区域。

有问题的特定页面允许用户通过输入数据并单击表单上的“保存”将新的Item 添加到数据库中。

Item 具有一些属性,它们都可以很好地添加到新行中。

Item 还包含一个针对它声明的List&lt;Appointment&gt;s(我会将它们序列化并将它们保存在适当的列中)。

对象看起来像这样(为简洁起见,我删除了一些属性):

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Appointment> Appointments { get; set; }
    // Plus some other properties
}

public class Appointment
{
    public string Day { get; set; }
    public string From { get; set; }
    public string To { get; set; }
}

我已经设置了一个要使用的 ViewModel,并且我正在练习所有通常的良好做法。它看起来像这样:

public class AddItemViewModel
{
    [Required(ErrorMessage = "Please enter an item name")]
    [Display(Name="Item Name")]
    public string Name { get; set; }

    [Display(Name="Appointments")]
    public List<Appointment> Appointments { get; set; }

    ...
    // Other properties in here
    ...
}

我正在使用 Razor 视图引擎。

使用@Html.EditorFor(x =&gt; x.Property) 助手,我一切正常;对于根对象 (Item's) 属性上的所有(除了一个 - 稍后告诉您)元素。

我可以将 ViewModel 发布到控制器并保存一个新的 Item 和所有爵士乐 - 所以那里一切都很好。

问题
我在 ViewModel 中声明了一个 List&lt;Appointment&gt;

如何允许用户从页面中将新的Appointments 添加到此List&lt;Appointment&gt;

我想将这些分配给要在发布 ViewModel 时创建的 Item 对象 - 我将在我的控制器/服务等中执行此操作。

我怎样才能做到这一点?

所需的视图
我需要用户能够从页面内添加Appointments - 最多可以添加他们喜欢的数量,真的。

我希望在页面上的某个区域中的列表(ul 或类似内容等)中有一个“已创建”Appointments 的列表。

在该列表下方,我想要一些与 AppointmentDayFromTo 属性相关的文本框 - 带有“添加”按钮,将其附加到列表中 (并清除文本框,理想情况下).

作为奖励,我还希望每个项目旁边有某种“×”式的“删除”按钮,以将其从 List&lt;Appointment&gt; 和视图中删除。

这是我想象的视图的示例(用 MSPaint - 老式工具 ftw 绘制!):

我尝试过的事情
我一直在广泛地挖掘,但到目前为止还没有任何东西可以帮助我。

  • 我已经查看了许多与在 页面的 JavaScript - 这确实有效。唯一的问题是我做不到 在发布到控制器的对象中拾取它们。

  • 也有人指出我直接使用 Ajax 创建一个 Appointment 对象并将其插入到页面中,但这似乎也没有被采纳。

    李>

非常感谢您的专业知识、知识和智慧。

【问题讨论】:

  • 参考答案herehere 了解一些选项
  • 谢谢@StephenMuecke - 看来您以前对这类事情有一些经验?我已经快速阅读了您链接的文章 - 第二个链接似乎更接近我所追求的。如果时间允许,我会更详细地进行适当的查看。同时,您是否可以为我的场景提供一些示例代码(我知道这可能是一个问)?
  • this DotNetFiddle 为例(您的Appointment 模型应该是DateTime DayTimeSpan FromTimeSpan To - 不是string
  • 喜欢那个.Net Fiddle!我会玩一玩,看看我得到了什么。仅供参考,出于某些其他原因,我故意将DayFromTo 属性创建为stringTL;DR - 不要惊慌,我不是那么菜鸟 :)
  • @StephenMuecke - 你需要去奖励自己一杯清爽的饮料,我的朋友!我已经设法调整您发布的 Fiddle 以适应我的需求。如果您想继续发布比 cmets 更详细的答案,我会将其标记为已接受 :)

标签: javascript c# asp.net-mvc viewmodel


【解决方案1】:
  1. 为了能够在 UI 上动态添加新的约会输入控件,点击添加按钮,您可以

[下面的代码来自我的头顶,更像是伪代码]

a) 使用 jQuery/js 克隆一个隐藏的 div,该 div 您已在包含所有相关约会控件的视图上预渲染。

例如这将是一个预渲染的 div,将用作模板

<div style="display:none;" id="appointment-template">
    <input type=text>
</div>

然后点击添加的 jQuery 克隆功能将类似于

var addNewAppointmentRowFromTemplate = function(){
        $("#appointments-list-container").append($("#appointment-template").clone());
    }

b) 从服务器获取部分视图并将其附加到表单(再次使用 jQuery $.get / js xhr)

 $.get( "controller/templatDivActionMethodUrl", function( data ) {
      $("#appointments-list-container").append( data );
    });
  1. 为了能够发送带有在 ActionMethod 的 Item 参数中接受的 List in Item 的模型,您可以

a) 使用 jquery/javascript 动态创建一个与服务器端模型结构相同的 json 对象(模型更改时可维护性将成为问题)。

    var appointmentsJson = [];
    //foreach loop is a pseudo code, can be replaced with $.each()
    foreach (var appointment in $("#appointments-list-container").children()){
            appointmentsJson.push(new {'day' : $(appointment).children("#day").val(),'from' : $(appointment).children("#from").val(),'to' : $(appointment).children("#to").val()})  ;}

    //and then post this json to actionMethod

    $.post("serverController/Actionmethod",{appointments: appointmentsJson});

b) 使用 ASP.Net MVC 附带的 ModelBinder 功能。我们那里有大量的文档/教程,这是一个起点: https://docs.asp.net/en/latest/mvc/models/model-binding.html

【讨论】:

  • 感谢您的建议。当我有更多时间时,我会愤怒地仔细看看他们。我之前尝试过将部分视图附加到表单中。不幸的是,MVC 的 ModelBinder 不会接受它 - 与索引有关吗? (正如@stephen-muecke 的链接所指出的那样)-因此我向 SO 的好人寻求帮助
  • 好酷。,...是的,CustomModelBinder 需要一个具有顺序索引的隐藏字段才能工作。
  • 现在我对事情有了清晰的认识,我再次查看了您的答案。完全正确(我没有怀疑)。 @Stephen Muecke 的 dotnetfiddle.net/UjxtUW 链接给了我正确的推动力,所以我已经要求他发布答案 - 正如我所看到的那样,这是公平的。如果他选择不这样做,您可以在您的答案中添加一些示例代码(对于未来的人来说最重要的是) - 我会考虑将其标记为已接受。再次感谢:)
  • 好的,听起来很公平。我从头顶添加了一些代码。
猜你喜欢
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
  • 2014-03-29
  • 2013-01-12
  • 1970-01-01
  • 2016-10-08
  • 2011-06-25
  • 1970-01-01
相关资源
最近更新 更多