ASP.NET MVC 保存列表<T> 到数据库
ASP.NET MVC Save List<T> to database
我在将列表项保存到数据库时遇到问题。当要保存一个字段时(在 HTTP POST Create 中),某些列表属性不必保存,因此我允许 nullabe 用于此类。但是,我从表单中检索并保存了一个字段。由于 classes 很复杂,我将在此处限制 post 的代码(我将使用一个字段,因为生成的异常是相同的)。
StringValues 是几个 List 字段继承自的 Class,例如本例中的 TestPlanChecklist。
public class TestPlanChecklist:StringValues
{
}
public class StringValues
{
[Key]
public int id { get; set; }
public int ChangeRequestsID { get; set; }
public string Value { get; set; }
public ChangeRequests ChangeRequests { get; set; }
}
我模型的一部分class
public class ChangeRequests
{
[Required]
public List<TestPlanChecklist> TestPlanChecklist { get; set; }
[Required]
public List<PostActivityChecklist> PostActivityChecklist { get; set; }
[Required]
public List<CMBApproval> CMBApproval { get; set; }
[Required]
public List<TechnicalFeasibility> TechnicalFeasibility { get; set; }
}
在我的创建视图中,这是为 TestPlanChecklist 字段呈现文本框的代码
<div class="form-group">
@Html.LabelFor(model => model.TestPlanChecklist, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div>
<label class="numbers"> 1 </label>
<input type="text" class="TestPlanChecklist" name="TestPlan" />
<input type="button" value="+" class="roundButton" onclick="add('TestPlanChecklist', 'TestPlan')" />
<input type="button" value="-" class="roundButton" onclick="removeElement('TestPlan')" />
</div>
<div>
<label class="numbers"> 2 </label>
<input type="text" class="TestPlanChecklist" name="TestPlan" />
</div>
<div>
<label class="numbers"> 3 </label>
<input type="text" class="TestPlanChecklist" name="TestPlan" />
</div>
@Html.ValidationMessageFor(model => model.TestPlanChecklist, "", new { @class = "text-danger" })
</div>
</div>
</div>
和HttpPost创建方法
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "TestPlanChecklist,PostActivityChecklist,PostActivityChecklist,CMBApproval,TechnicalFeasibility")] ChangeRequests changeRequests,
string[] TestPlan)
{
changeRequests.TestPlanChecklist = new List<TestPlanChecklist>();
foreach (var test in TestPlan)
changeRequests.TestPlanChecklist.Add(new TestPlanChecklist { Value = test });
//SendEmails(TechnicalFeasibility, User.Identity.Name, ChangeUrgency, Priority, DescriptionOfChange, Reason);
//SendEmails(CMBApproval, User.Identity.Name, ChangeUrgency, Priority, DescriptionOfChange, Reason);
if (ModelState.IsValid)
{
db.ChangeRequests.Add(changeRequests);
db.SaveChanges();
return RedirectToAction("List");
}
return View(changeRequests);
}
请注意,我只使用一个字段来问这个问题,这就是为什么我删除了用于初始化其他列表字段的代码的原因。
ModelState.IsValid
returns 错误。我意识到所有 List 字段都有一个错误,它表明无法从 System.String 类型转换为特定的 class。这很有趣,因为我只分配了一个从表单中检索到的字段值,其余的都可以为空,这很有意义。
我哪里错了?
提前致谢。
您可以检查验证的错误。
var errores = new List<ModelError>();
foreach (ModelState modelState in ViewData.ModelState.Values)
{
foreach (ModelError error in modelState.Errors)
{
errores.Add(error);
}
}
ModelState.IsValid
检查验证规则,在您的案例中来自 DataAnnotations
[Required]
ChangeRequests
ViewModel 中的属性。
如果您想使用此验证并使您的某些 List
属性可为空,您应该删除此属性。
您收到 ModelState 错误,因为 ChangeRequest
具有 [Required]
属性并由 Mvc 验证。我不清楚您为什么要使用该动作签名,但这是一种不好的方法。您应该直接依赖 ViewModels
而不是 Models
。
public ActionResult Create(ChangeRequestViewModel viewModel)
{
if(ModelState.IsValid == false) return View(viewModel);
var changeRequest = new ChangeRequest();
foreach(var testPlan in viewModel.TestPlans) {
changeRequest.TestPlanChecklist.Add(new TestPlanChecklist { Value = testPlan }
}
// ...
}
我在将列表项保存到数据库时遇到问题。当要保存一个字段时(在 HTTP POST Create 中),某些列表属性不必保存,因此我允许 nullabe 用于此类。但是,我从表单中检索并保存了一个字段。由于 classes 很复杂,我将在此处限制 post 的代码(我将使用一个字段,因为生成的异常是相同的)。
StringValues 是几个 List 字段继承自的 Class,例如本例中的 TestPlanChecklist。
public class TestPlanChecklist:StringValues
{
}
public class StringValues
{
[Key]
public int id { get; set; }
public int ChangeRequestsID { get; set; }
public string Value { get; set; }
public ChangeRequests ChangeRequests { get; set; }
}
我模型的一部分class
public class ChangeRequests
{
[Required]
public List<TestPlanChecklist> TestPlanChecklist { get; set; }
[Required]
public List<PostActivityChecklist> PostActivityChecklist { get; set; }
[Required]
public List<CMBApproval> CMBApproval { get; set; }
[Required]
public List<TechnicalFeasibility> TechnicalFeasibility { get; set; }
}
在我的创建视图中,这是为 TestPlanChecklist 字段呈现文本框的代码
<div class="form-group">
@Html.LabelFor(model => model.TestPlanChecklist, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div>
<label class="numbers"> 1 </label>
<input type="text" class="TestPlanChecklist" name="TestPlan" />
<input type="button" value="+" class="roundButton" onclick="add('TestPlanChecklist', 'TestPlan')" />
<input type="button" value="-" class="roundButton" onclick="removeElement('TestPlan')" />
</div>
<div>
<label class="numbers"> 2 </label>
<input type="text" class="TestPlanChecklist" name="TestPlan" />
</div>
<div>
<label class="numbers"> 3 </label>
<input type="text" class="TestPlanChecklist" name="TestPlan" />
</div>
@Html.ValidationMessageFor(model => model.TestPlanChecklist, "", new { @class = "text-danger" })
</div>
</div>
</div>
和HttpPost创建方法
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "TestPlanChecklist,PostActivityChecklist,PostActivityChecklist,CMBApproval,TechnicalFeasibility")] ChangeRequests changeRequests,
string[] TestPlan)
{
changeRequests.TestPlanChecklist = new List<TestPlanChecklist>();
foreach (var test in TestPlan)
changeRequests.TestPlanChecklist.Add(new TestPlanChecklist { Value = test });
//SendEmails(TechnicalFeasibility, User.Identity.Name, ChangeUrgency, Priority, DescriptionOfChange, Reason);
//SendEmails(CMBApproval, User.Identity.Name, ChangeUrgency, Priority, DescriptionOfChange, Reason);
if (ModelState.IsValid)
{
db.ChangeRequests.Add(changeRequests);
db.SaveChanges();
return RedirectToAction("List");
}
return View(changeRequests);
}
请注意,我只使用一个字段来问这个问题,这就是为什么我删除了用于初始化其他列表字段的代码的原因。
ModelState.IsValid
returns 错误。我意识到所有 List 字段都有一个错误,它表明无法从 System.String 类型转换为特定的 class。这很有趣,因为我只分配了一个从表单中检索到的字段值,其余的都可以为空,这很有意义。
我哪里错了?
提前致谢。
您可以检查验证的错误。
var errores = new List<ModelError>();
foreach (ModelState modelState in ViewData.ModelState.Values)
{
foreach (ModelError error in modelState.Errors)
{
errores.Add(error);
}
}
ModelState.IsValid
检查验证规则,在您的案例中来自 DataAnnotations
[Required]
ChangeRequests
ViewModel 中的属性。
如果您想使用此验证并使您的某些 List
属性可为空,您应该删除此属性。
您收到 ModelState 错误,因为 ChangeRequest
具有 [Required]
属性并由 Mvc 验证。我不清楚您为什么要使用该动作签名,但这是一种不好的方法。您应该直接依赖 ViewModels
而不是 Models
。
public ActionResult Create(ChangeRequestViewModel viewModel)
{
if(ModelState.IsValid == false) return View(viewModel);
var changeRequest = new ChangeRequest();
foreach(var testPlan in viewModel.TestPlans) {
changeRequest.TestPlanChecklist.Add(new TestPlanChecklist { Value = testPlan }
}
// ...
}