为什么复选框选择列表始终在ASP.NET MVC-5中发布为null

时间:2017-09-10 05:51:17

标签: asp.net-mvc asp.net-mvc-5

我是ASP .NET MVC的新手。我的问题是 - 我想' POST'项目的集合,以便控制器可以处理它。 我的模型是 -

的集合
public class CheckedRentalProperty
{
   public bool IsSelected { get; set; }
   public int Id { get; set; }
   public String Address { get; set; }
}

我的控制器定义如下 -

public class RentalPropertiesController : Controller
{
    public ActionResult Index()
    {
        List<CheckedRentalProperty> checkHsList = new List<CheckedRentalProperty>();
        // Fill the list
        return View(checkHsList);
    }

    [HttpPost]
    public ActionResult Save(IEnumerable<CheckedRentalProperty> checkHsList)
    {
        // why checkHsList is coming as null ??
    }
}

视图就是这样 -

@model IEnumerable<XXX.Models.CheckedRentalProperty>

@using (Html.BeginForm("Save", "RentalProperties", FormMethod.Post))
{
    <div class="form-horizontal">
        <div class="form-group">
            <table class="table">
                <tr>
                    <th>

                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.Address)
                    </th>

                </tr>

                @foreach (var item in Model)
                {
                    <tr>
                        <td>@Html.CheckBoxFor(modelItem => item.IsSelected)</td>

                        <td>
                            @Html.DisplayFor(modelItem => item.Address)
                        </td>
                    </tr>
                }
            </table>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

我的期望是 - 当我点击&#34; Save&#34;按钮,Model为IEnumerable<CheckedRentalProperty>项,将传递给控制器​​的Save()动作。但是,我发现传递的参数是&#34; null&#34;每时每刻。我错过了什么?

1 个答案:

答案 0 :(得分:0)

仅IEnumerable的模型不像MVC Model那样友好。

这里出现了很多问题,但简而言之,MVC webform绑定需要以下列格式发送表单名称请求:PropertyName[Index].Property 在你的例子中并非如此。

这是一个很好的设计实践,创建一个包装ViewModel,它将保存给定控制器+页面所需的属性。

<强>视图模型

public class RentalPropertiesViewModel
{
    public List<CheckedRentalProperty> CheckedRentalProperties { get; set; }
}

控制器:接下来,我们将在控制器中使用此ViewModel。

public ActionResult Index()
{
    var checkHsList = new List<CheckedRentalProperty>();
    checkHsList.Add(new CheckedRentalProperty { Id = 1, Address = "Address1", IsSelected = true });
    checkHsList.Add(new CheckedRentalProperty { Id = 2, Address = "Address2", IsSelected = false });
    checkHsList.Add(new CheckedRentalProperty { Id = 3, Address = "Address3", IsSelected = true });

    var model = new RentalPropertiesViewModel
    {
        CheckedRentalProperties = checkHsList
    };
    return View(model);
}

[HttpPost]
public ActionResult Save(RentalPropertiesViewModel model)
{
    // why checkHsList is coming as null ??

    return null;
}

查看:现在我们应该将模型设置为我们创建的新ViewModel类型。

@model TestBindings.Models.RentalPropertiesViewModel

我们的观点形式应该是:

<table class="table">
    <tr>
        <th>
            Is Selected
        </th>
        <th>
            Address
        </th>

    </tr>
    @for (int i = 0; i < Model.CheckedRentalProperties.Count(); i++)
    {
        <tr>
            @Html.HiddenFor(model => model.CheckedRentalProperties[i].Id);
            <td>@Html.CheckBoxFor(model => model.CheckedRentalProperties[i].IsSelected)</td>

            <td>@Html.TextBoxFor(model => model.CheckedRentalProperties[i].Address)</td>
        </tr>
    }
</table>

我使用以下格式model => model.CheckedRentalProperties[i].IsSelected,现在MVC InputExtensions会正确绑定它。 例如: CheckedRentalProperties[0].IsSelected

重要提示:请注意,我将Id属性设为隐藏,因此MVC Binder会知道将Id设置为正确的项目。