I have a problem saving List items to database. When a field is to be saved(in HTTP POST Create) some of the Lists properties don't have to be saved so I have allowed nullabe for such. However there is one field that I retrieve from the Form and save it. Since the classes are complex I'll restrict the code I'll post here (I'll use one field since the Exception generated is the same).
StringValues is the Class that several List fields inherit from, such as TestPlanChecklist in this case.
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; }
}
Part of my Model 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; }
}
In my Create view, this is the code that renders textboxes for TestPlanChecklist field
<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>
And HttpPost Create method
[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);
}
Kindly note that am just using one field to ask this question, thats why I have removed code for initializing the other List fields.
ModelState.IsValid
returns false. I realize that all the List fields have an error, which states that its impossible to typecast from System.String to the particular class. This is funny since I assign only one field value retrieved from the form and the rest are nullable which makes sense.
Where am I going wrong?
Thanks in advance.
nameattribute "TestPlan", which has no relationship to your model. Why does you POST method have the parameterChangeRequests changeRequests? - you don't post anything related to any properties of typeChangeRequestsso validation will always fail because of the[Required]attribute. You also have aLabelFor()andValidationMessageFor()ssociated with propertyTestPlanChecklistwhich makes no sense (again you don't generate any form controls for any properties ofTestPlanChecklist!)ValidationMessageFor()andLabelFor()since the form controls with the name TestPlan set one property of theTestPlanChecklist. I set the other fields on the HTTP POST method and some of them will be set (updated) later on during the applications use.ChangeRequests! But what you should have is a view model that isList<string> TestPlanand post that back if its the only thing you are editing.