【问题标题】:Null reference when trying to post with ViewModel尝试使用 ViewModel 发布时的空引用
【发布时间】:2015-05-20 10:40:32
【问题描述】:

目前我有一个 ViewModel,它由 2 个模型列表组成。使用 ViewModel 显示内容很好,但是当我尝试发布时,我得到一个空引用异常。

public class DashboardViewModel
{
    public IList<DashboardModel> dashboard { get; set; }
    public IList<WidgetModel> widgets { get; set; }
}

这是视图上的表单

 @using (Html.BeginForm("AddDashboard", "Dashboard", FormMethod.Post))
            {
                @Html.AntiForgeryToken()

                <div class="form-horizontal">
                    <h4>DashboardModel</h4>
                    <hr />
                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                    <div class="form-group">
                        @Html.LabelFor(model => model.dashboard.Last().DashName, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.dashboard.Last().DashName, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.dashboard.Last().DashName, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                            <button type="submit" value="AddDashboard" class="btn btn-primary">Save changes</button>
                        </div>
                    </div>
                </div>
            }

这是我的行动

 [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AddDashboard([Bind(Include = "DashID,DashName,CreatedBy,CreatedDate")] DashboardViewModel dashboardVM)
    {
        if (ModelState.IsValid)
        {
            DashboardModel newDashboard = dashboardVM.dashboard.Last();
            newDashboard.CreatedBy = User.Identity.GetUserId();
            newDashboard.CreatedDate = DateTime.Now;

            db.dashboards.Add(newDashboard);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(dashboardVM);
    }

空引用发生在 AddDashboard 操作中我设置了断点并意识到dashboardVM为null,dashboard属性为null

【问题讨论】:

  • 您没有生成与您的模型无关的控件。属性dashboard 是一个集合,因此您需要在for 循环中生成控件(或为DashboardModel 类型使用自定义EditorTemplate
  • 您没有发回列表。更改发布操作以接受 DashboardModel。
  • @Html.EditorFor(model =&gt; model.dashboard.Last().DashName, ... 不起作用,因为 .Last()IEnumerable,因此是只读的。
  • 看看你生成的html。为了绑定你的控件需要&lt;input name="dashboard[0].DashName" ..&gt;,你需要删除[Bind]属性
  • @BrendanGreen 这解决了我的问题,谢谢,你想把它作为答案,以便我给你一个绿色的勾吗?

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


【解决方案1】:

您的[Bind] 属性导致您的视图模型的dashboard(和widgets)属性保持为空,因为您没有在dashboard 列表中包含dashboard

尝试从您的操作参数中删除 [Bind] 并将其放在 DashboardModel 本身上:

[Bind(Include = "DashID,DashName,CreatedBy,CreatedDate")]
public class DashboardModel
{
    // ...
}

MSDN

【讨论】:

  • 我已按照您的指示进行操作,但这似乎并没有解决我的问题
  • 这似乎只是部分问题,另一个问题与您对EditorFor()的使用有关。稍后会研究这个
【解决方案2】:

您的HttpPost 操作正在接收DashboardViewModel,它在内部包含DashboardModel 的集合以及其他属性。

但是,您传递的不是任何东西的集合,而是一个 DashboardModel

更新您的操作以改为接受DashboardModel

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddDashboard([Bind(Include = "DashID,DashName,CreatedBy,CreatedDate")] DashboardModel dashboardVM)
{
    ...
}

注意:[Bind] 属性可能需要调整;您还没有提供DashboardModel 类的定义。

【讨论】:

    猜你喜欢
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    相关资源
    最近更新 更多