EDIT - as requested, this is the view...
--start edit
@model salesWebTest.viewModel.vwbooking
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.bookings.bookingid)
@Html.EditorFor(model => model.bookings.name)
@foreach (var item in Model.traces)
{
@Html.EditorFor(m => item.contact_Name)
}
}
--end edit
--start original question I have a viewModel that contains two classes...
public class vwbooking
{
public booking bookings { get; set; }
public IEnumerable<trace> traces { get; set; }
}
Booking and trace are entities in an edmx.
I want to update the data in these two class with one call to save.
This is what I've tried...
public ActionResult Edit(vwbooking vwbooking)
{
if (ModelState.IsValid)
{
db.bookings.Attach(vwbooking.bookings);
db.Entry(vwbooking.bookings).State = EntityState.Modified;
vwbooking.traces.ToList().ForEach( //THE ERROR OCCURS HERE
t =>
{
db.traces.Attach(t);
db.Entry(t).State = EntityState.Modified;
});
db.SaveChanges();
}
}
If I remove the traces portion, the booking portion will update correctly.
This is the GET method...
public ActionResult Edit(int id = 0)
{
booking booking = db.bookings.Find(id);
var viewModel = new vwbooking();
viewModel.bookings = booking;
viewModel.traces = (from l in db.traces where l.bookingid == booking.bookingid select l);
return View(viewModel);
}
This is my db context class
public class salesContext : DbContext
{
public salesContext() : base()
{
Configuration.LazyLoadingEnabled = true;
}
public salesContext(string Connection) : base(Connection)
{
Configuration.LazyLoadingEnabled = true;
}
public DbSet<booking> bookings { get; set; }
public DbSet<trace> traces { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<booking>().HasKey(e => e.bookingid);
modelBuilder.Entity<trace>().HasKey(e => e.traceid);
}
}
The issue appears to be the way the editor is setup. I believe that this is causing the model to not properly bind on submit
@Html.EditorFor(m => item.contact_Name)
If you were to inspect the name
attribute of the <input>
element generated by this helper, you will more than likely see that it reads
<input name="item.contact_Name" />
for every one of these. It may even just say name="contact_Name"
.
This is a severe drawback of the framework and the workarounds for it are usually to make a whole custom helper or to use a front end solution to fix the names.
The name must match exactly to the model. What it should be for your values is
<input name="traces[0].contact_Name" />
<input name="traces[1].contact_Name" />
etc..
and so I would suggest figuring out a way that works with your current project to make sure that those names get properly set.
Your not checking if vwbooking.traces == null before calling it. While you might expect that .ToList() can protect you from this, Entity Framework can be quirky (anecdotal). Safeguard your call with
if (ModelState.IsValid)
{
db.bookings.Attach(vwbooking.bookings);
db.Entry(vwbooking.bookings).State = EntityState.Modified;
if(vwbooking.traces != null)
{
vwbooking.traces.ToList().ForEach( //THE ERROR OCCURS HERE
t =>
{
db.traces.Attach(t);
db.Entry(t).State = EntityState.Modified;
}
);
db.SaveChanges();
}
}
and you should be fine.
来源:https://stackoverflow.com/questions/19432776/getting-error-on-post-with-entity-framework-value-cannot-be-null-parameter-na