首页 > 解决方案 > 如何将模型列表传递给控制器

问题描述

我正在尝试将 View 中的对象列表发布到控制器。

下面是我的代码:

看法 :

    @using Models
    @model IList<Add>
    @{
        ViewData["Title"] = "AddNewFields";
    }
    <form asp-controller="Trans" asp-action="InsertFields" method="post" class="form-horizontal card-body" role="form">
<td><input type="text" class="form-control" value="Field Size" asp-for="@Model[i].TypeFlag"/></td>
                            <td><input type="text" class="form-control" value="Field Value" asp-for="@Model[i].FieldValue"/></td>
                            <td><input type="text" class="form-control" value="Field Format" asp-for="@Model[i].FieldFormat"/></td>
</form>  

我将在按钮单击时再次添加这些文本字段。

模型:

public class Add
    {        
        public string TypeFlag { get; set; }

        public string FieldValue { get; set; }

        public string FieldFormat { get; set; }
    }

控制器:

public string InsertFields(IList<Add> fields)
{
            //some logic
}

当我运行应用程序时,我收到以下错误:

NullReferenceException: Object reference not set to an instance of an object.

    AspNetCore.Views_Trans_Add.<ExecuteAsync>b__27_0() in AddNewFields.cshtml

            @for (int i = 0; i < Model.Count; i++)

Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.GetChildContentAsync(bool useCachedResult, HtmlEncoder encoder)
Microsoft.AspNetCore.Mvc.TagHelpers.RenderAtEndOfFormTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.RunAsync(TagHelperExecutionContext executionContext)

请帮帮我...我被困在这里两天了..

标签: asp.net.netasp.net-mvcasp.net-core-mvcasp.net-core-2.0

解决方案


2个问题:

  1. 模型为空
  2. 行动不会得到价值。

解决方案:

你的 HTML 应该是这种风格

@{
    var fields = (Model ?? Enumerable.Empty<Add>()).ToList(); //this variable must be same with the parameter in action.
}

<form asp-action="Test" method="post">
    <table class="table">
        <tbody>
            <tr>
                <td>
                    <div class="form-group">
                        <input type="submit" value="Submit" />
                    </div>
                </td>
            </tr>
            @for (var i = 0; i < fields.Count; i++) //you must use for, not foreach
            {
                <tr>
                    <td>
                        <div class="form-group">
                            <input type="hidden" asp-for="@fields[i].Id" />
                            <input asp-for="@fields[i].Name" class="form-control" />
                        </div>
                    </td>
                </tr>
            }
        </tbody>
    </table>
</form>

你的控制器应该是这样的:

    [HttpPost]
    public async Task<IActionResult> Test(IEnumerable<Add> fields)
    //be aware: the parameter name "fields" must be same with your html
    //the type should be "IEnumerable<Add>", more compatible with different versions of MVC
    {
        .....your logic
        return Json(new { ... });
    }

生成的html是这种风格:

 <tr>
    <td>
        <div class="form-group">
            <input type="hidden" id="fields_0__Id" name="fields[0].Id" value="14">
            <input class="form-control" type="text" id="fields_0__Name" name="fields[0].Name" value="xxxxx">
        </div>
    </td>
</tr>
<tr>
    <td>
        <div class="form-group">
            <input type="hidden" id="fields_1__Id" name="fields[1].Id" value="1">
            <input class="form-control" type="text" id="fields_1__Name" name="fields[1].Name" value="xxxx">
        </div>
    </td>
</tr>

你会看到原因:参数fields只是html表单的一个字段,它们必须相互匹配。


推荐阅读