ASP.NET MVC将列表<t>保存到数据库

时间:2015-05-26 14:45:34

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

我将列表项目保存到数据库时遇到问题。当要保存字段时(在HTTP POST创建中),某些列表属性不必保存,所以我已经允许nullabe这样做。但是,我从表单中检索了一个字段并保存它。由于类很复杂,我将限制我在这里发布的代码(因为生成的异常是相同的,所以我将使用一个字段)。

StringValues是多个List字段继承的类,例如本例中的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; }
}

我的Model类的一部分

    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);
    }

请注意,我只是使用一个字段来提出这个问题,这就是为什么我删除了用于初始化其他List字段的代码。

ModelState.IsValid

返回false。我意识到所有List字段都有一个错误,它指出不可能从System.String转换为特定的类。这很有趣,因为我只分配从表单中检索到的一个字段值,其余字段值可以为空,这是有意义的。

我哪里错了?

提前致谢。

3 个答案:

答案 0 :(得分:1)

您可以检查验证错误。

var errores = new List<ModelError>();
foreach (ModelState modelState in ViewData.ModelState.Values)
{
    foreach (ModelError error in modelState.Errors)
    {
        errores.Add(error);
    }
}

答案 1 :(得分:1)

ModelState.IsValid检查验证规则,该规则来自您DataAnnotations [Required] <{1>} ViewModel 中的ChangeRequests属性。

如果您想使用此验证并使某些List属性可以为空,则应删除此属性。

答案 2 :(得分:1)

您收到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 }
    }
    // ...
}