将 ViewModel 传递给 Controller 并不完全有效

Passing ViewModel to Controller doesn't fully work

我花了一整天的时间在网上搜索解决方案,但是我找不到解决我的错误的方法。它变得非常令人沮丧,我有一种感觉,就是那些 facepalm 错误。希望大家有时间帮帮我。

我正在创建一个使用 ViewModel 的视图。我正在使用 BeginForm 并提交输入类型按钮。现在它传递了 ViewModel 中的第一个 属性,但其他每个 属性 都传递为 null。

这是我的 ViewModel + 模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FitnessSundhed.Models;
namespace FitnessSundhed.ViewModels
{
    public class WorkoutViewModel
    {
        public Workouts Workout { get; set; }
        public Sets Sets { get; set; }
        public Execises Execises { get; set; }
    }
}

其中一些 属性 应该列出,但我选择不列出它们,直到我尝试这样做以防出现问题。别介意。

这是锻炼模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace FitnessSundhed.Models
{
    public class Workouts
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public string Author { get; set; }

        public string Description { get; set; }

        public string Equipment { get; set; }

        public string Targets { get; set; }

        public List<Sets> Sets { get; set; }


    }

}

设置模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace FitnessSundhed.Models
{
    public class Sets
    {
        public int Id { get; set; }
        public string SetName { get; set; }
        public string SetDesc { get; set; }

        public List<Execises> Execises { get; set; }
    }
}

执行模型

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace FitnessSundhed.Models
{
    public class Execises
    {
        public int Id { get; set; }
        public string ImagePath { get; set; }
        public string Name { get; set; }
        public int Reps { get; set; }
        public string Note { get; set; }

    }
}

基本上锻炼包含一个集合列表,其中包含一个练习列表。

查看

@model FitnessSundhed.ViewModels.WorkoutViewModel

@{
    ViewBag.Title = "Action";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Action</h2>

@using (Html.BeginForm("Create", "Workouts", FormMethod.Post, null))
{
    @Html.AntiForgeryToken()

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

    <div class="form-group">
        @Html.LabelFor(model => model.Workout.Author, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Workout.Author, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Workout.Author, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Workout.Description, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Workout.Description, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Workout.Description, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Workout.Equipment, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Workout.Equipment, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Workout.Equipment, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Workout.Targets, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Workout.Targets, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Workout.Targets, "", new { @class = "text-danger" })
        </div>
    </div>


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

    <div class="form-group">
        @Html.LabelFor(model => model.Sets.SetDesc, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Sets.SetDesc, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Sets.SetDesc, "", new { @class = "text-danger" })
        </div>
    </div>



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

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

控制器

[HttpPost]
        public ActionResult Create(WorkoutViewModel model)
        {
            Workouts workout = new Workouts();
            workout = model.Workout;
            workout.Sets.Add(model.Sets); // NullReferenceException here.
            _context.Workoutss.Add(workout);
            _context.SaveChanges();
            return RedirectToAction("Library", "Workouts");
        }

练习尚未编码。

总而言之。视图可以传递 ViewModel 并且我可以将 Workout 添加到数据库中(我以前做过),但是当我尝试使用 Sets 或 Execises 时,我得到 ''System.NullReferenceException: 'Object reference not set to an instance of an object.'' 当我尝试将设置添加到控制器中的锻炼时出错。

我希望我已经详细描述了它。如果没有,请询​​问更多信息。

您的模型一开始是空白。

Workouts workout = new Workouts();

这意味着除非列表存在,否则您无法将其添加到列表中。所以当你打电话给

workout.Sets.Add(model.Sets); // NullReferenceException here.

workout.Sets 为空。您的对象永远不会初始化它。

在您的模型中执行此操作。

public List<Sets> Sets { get; set; } = new List<Sets>();

相反,如果有时您不希望它初始化(ORM 绑定很生气或其他),请确保在使用它之前先调用它,就像这样。

 Workouts workout = new Workouts();
            workout = model.Workout;
            workout.Sets = new List<Sets>();
            workout.Sets.Add(model.Sets);