c# - MVC Razor 创建要提交的对象列表

标签 c# asp.net-mvc-5

我是一位经验丰富的 .NET C# 软件开发人员,但仅在几个月前我才开始使用 MVC Razor (MVC 5)。

我有一个小问题,我在网上找不到任何答案(经过数小时的搜索)

我有一个模型,它有另一个模型的列表,而另一个模型又有一个模型列表,如下所示。

public class Parent
{
    public string Name { get; set; }
    public string Sex { get; set; }
    public int Age { get; set; }
    public List<Child> Children { get; set; } 
}

public class Child
{
    public string Name { get; set; }
    public string Sex { get; set; }
    public int Age { get; set; }
    public List<GrandChild> GrandChildren { get; set; } 
}

public class GrandChild
{
    public string Name { get; set; }
    public string Sex { get; set; }
    public int Age { get; set; }
}

我的Controller有2个方法,一个是main Get,一个是post,用来post新数据

public ActionResult Index()
{
    return View();
}

[HttpPost]
public ActionResult PostParent(Parent parent)
{
    if (ModelState.IsValid)
    {
        //Do an insert to the DB
        return View("~/Views/Home/Index.cshtml");
    }

    return Json("Error");
}

但是在我的 View in Form 中,我找不到创建添加按钮并将新数据插入 Children 和 GrandChildren(如果是 Child)列表的方法

@using (Html.BeginForm("PostParent", "Home", FormMethod.Post, new {@class = "form-horizontal", role = "form"}))
{
    @Html.LabelFor(x => x.Name)
    @Html.TextBoxFor(x => x.Name)
}

我只能为原始类型属性添加字段,不能为对象添加字段。

如果有任何帮助,我将不胜感激!

最佳答案

为此你可以使用Html.BeginCollectionItem https://www.nuget.org/packages/BeginCollectionItem/

您可以为主窗体创建一个 View 并将 Parent 模型传递给它,因为这将代表父级,然后您将需要一行来代表一个子级,您可以调用这个 ChildRow.cshtml

因此,我们正在为父模型创建 Create.cshtml View ,我们将传递给父模型。

@model Parent

@using(Html.BeginForm())
{
   @Html.TextBoxFor(m => m.Name)


    <table id="children">
        <tbody>

<!-- This here will display the Child Row for existing Rows in the Parent model -->

            @foreach (var child in Model.Children )
            {
                @Html.Partial("ChildRow", child)
            }
        </tbody>

    </table>
<button  type="button" id="addChild">Add Child</button>

<button type="submit"> Save</button>
    }

这就是 ChildRow.cshtml 的样子,它将有一个 Child 模型。

注意:您必须将 IsDeleted 属性添加到子模型,这将帮助您在 Controller 中查看子模型是否被删除。

@model Child

@using (Html.BeginCollectionItem("Children"))
{
    <tr>
        <td>
             @Html.HiddenFor(m => m.IsDeleted, new { data_is_deleted = "false" })
            @Html.HiddenFor(m => m.ChildId)
            @Html.TextBoxFor(m => m.Name )
        </td>

        <td>
             <span class="glyphicon glyphicon-trash action-icon" data-action="removeItem"></span>
        </td>


    <tr>
}

现在,当单击 Add Child 按钮时,您必须在表格末尾添加一行。

为此,您将在 Controller 中创建一个新操作:

    public ActionResult AddChild()
    {
        return PartialView("Child", new Child());
    }

然后将这个 jQuery 添加到 Create.cshtml

    $("#addChild").on("click", function () {
        $.ajax({
            url: '@Url.Action("AddChild", "YourController")'
        }).success(function (partialView) {
            $('#children> tbody:last-child').append(partialView);
        });
    });

这将向表中添加一个新的子行

此外,如果您还想在同一页面上删除,则必须隐藏/禁用该行,为此您可以添加此 jQuery:

$('body').on("click", '*[data-action="removeItem"]', function (e) {
    e.stopPropagation();
    var btn = $(this);
    var row = btn.closest('tr');
    var firstCell = $(row.find('td')[0]);
    var checkBox = firstCell.find('*[data-is-deleted]');
    var checkBoxVal = checkBox.val();

    if (checkBoxVal === 'False' || checkBox.val() === 'false') {
        checkBox.val('true');
        row.find('td').find('input, textarea, select').attr('readonly', 'readonly');
    } else {
        checkBox.val('false');
        row.find('td').find('input, textarea, select').attr("readonly", false);
    }

});

然后,当您 POST 回 Controller 时,您将看到模型中的子项列表。

[HttpPost]
public ActionResult Create(Parent model)
{

   var newChildren = model.Children.Where(s => !s.IsDeleted && s.ChildId == 0);

   var updated = model.Children.Where(s => !s.IsDeleted && s.ChildId != 0);

   var deletedChildren = model.Children.Where(s => s.IsDeleted && s.ChildId != 0);


    return View(model);
}

您必须为孙子做类似的事情。

关于c# - MVC Razor 创建要提交的对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35989641/

相关文章:

c# - 如何从 Asp.Net Core View 组件返回错误的 HTTP 状态代码

javascript - ASP.NET MVC 组合框

asp.net-mvc - 当调试为假且存在缩小文件时,忽略 ASP.NET MVC 包中的自定义脚本转换

asp.net-mvc - 如何使用 ASP.NET Identity (OWIN) 访问 Facebook 私有(private)信息?

javascript - 如何在外部浏览器中打开 anchor 标记链接,而不是在 xamarin.forms 中的同一 Web View 中打开

c# - 在 C# 中处理非常大的二进制字符串

c# - 将 C# 字符串变量插入到 ASP.NET 代码后面的 Javascript 警报中

c# - MVC Razor View 中的 HTML.Textarea 值

iis - Azure 网站规范主机名规则 - 循环重定向

c# - 使用日期时间和日期选择器