将 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);
我花了一整天的时间在网上搜索解决方案,但是我找不到解决我的错误的方法。它变得非常令人沮丧,我有一种感觉,就是那些 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);