TECHNOLOGIES
FORUMS
JOBS
BOOKS
EVENTS
INTERVIEWS
Live
MORE
LEARN
Training
CAREER
MEMBERS
VIDEOS
NEWS
BLOGS
Sign Up
Login
No unread comment.
View All Comments
No unread message.
View All Messages
No unread notification.
View All Notifications
Answers
Post
An Article
A Blog
A News
A Video
An EBook
An Interview Question
Ask Question
Forums
Monthly Leaders
Forum guidelines
Darren Brook
NA
30
13.2k
Updating Master-Detail / Parent-Child data in MVC
Apr 30 2018 5:40 AM
I have a view with a master-detail style view for an invoice. Master is invoice, detail is invoice lines. I'm trying to get detail data items to save on upon an edit post but the detail data is lost upon reaching the post Edit on the controller. So the master data saves fine but the detail is obviously not saved.
Invoice Class:
public
class
Invoice
{
public
Invoice()
{
}
[Required]
[Key]
public
int
InvoiceID {
get
;
set
; }
[Required]
[StringLength(30)]
[DisplayName(
"Invoice Number"
)]
public
string
InvoiceNumber {
get
;
set
; }
[Required, DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[DataType(DataType.Date)]
[Column(TypeName =
"Date"
)]
[DisplayName(
"Invoice Date"
)]
public
DateTime InvoiceDate {
get
;
set
; }
public
List
InvoiceLines {
get
;
set
; }
[ForeignKey(
"Client"
)]
public
int
OwnerClientIDFK {
get
;
set
; }
[DisplayName(
"Client"
)]
public
Client Client {
get
;
set
; }
}
Invoice Line class:
public
class
InvoiceLine
{
public
InvoiceLine()
{
}
[Key]
[Required]
public
int
InvoiceLineId {
get
;
set
; }
[Required]
[StringLength(255)]
[DisplayName(
"Item"
)]
public
string
ItemName {
get
;
set
; }
[DisplayName(
"Description"
)]
public
string
ItemDescription {
get
;
set
; }
[Required]
public
int
Quantity {
get
;
set
; }
[Required]
[DisplayFormat(DataFormatString =
"{0:C}"
, ApplyFormatInEditMode =
true
)]
public
decimal
Value {
get
;
set
; }
[ForeignKey(
"ParentInvoice"
)]
public
int
InvoiceID {
get
;
set
; }
public
Invoice ParentInvoice {
get
;
set
; }
}
Controller Edit (get):
public
ActionResult Edit(
int
? id)
{
if
(id ==
null
)
{
return
new
HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// Invoice invoice = db.Invoices.Find(id);
Invoice invoice = db.Invoices.Include(i => i.InvoiceLines)
.Include(i => i.Client)
.Where(c => c.InvoiceID == id).FirstOrDefault();
if
(invoice ==
null
)
{
return
HttpNotFound();
}
ViewBag.OwnerClientIDFK =
new
SelectList(db.Clients,
"ClientId"
,
"CompanyName"
, invoice.OwnerClientIDFK);
return
View(invoice);
}
Controller Edit (post):
public
ActionResult Edit([Bind(Include =
"InvoiceID,InvoiceNumber,InvoiceDate,OwnerClientIDFK"
)] Invoice invoice)
{
if
(ModelState.IsValid)
{
db.Entry(invoice).State = EntityState.Modified;
foreach
(var invLine
in
invoice.InvoiceLines)
{
db.Entry(invLine).State = EntityState.Modified;
}
db.SaveChanges();
return
RedirectToAction(
"Index"
);
}
ViewBag.OwnerClientIDFK =
new
SelectList(db.Clients,
"ClientId"
,
"CompanyName"
, invoice.OwnerClientIDFK);
return
View(invoice);
}
So in the above, when it reaches the foreach, it throws an exception because InvoiceLines is null.
View:
@model DemoApp.Entities.Invoice
@{
ViewBag.Title
=
"Edit"
;
}
<
h2
>
Edit
</
h2
>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<
div
class
=
"form-horizontal"
>
<
h4
>
Invoice
</
h4
>
<
hr
/>
@Html.ValidationSummary(true, "", new { @
class
=
"text-danger"
})
@Html.HiddenFor(
model
=
>
model.InvoiceID)
<
div
class
=
"form-group"
>
@Html.LabelFor(
model
=
>
model.InvoiceNumber, htmlAttributes: new { @
class
=
"control-label col-md-2"
})
<
div
class
=
"col-md-10"
>
@Html.EditorFor(
model
=
>
model.InvoiceNumber, new {
htmlAttributes
=
new
{ @
class
=
"form-control"
} })
@Html.ValidationMessageFor(
model
=
>
model.InvoiceNumber, "", new { @
class
=
"text-danger"
})
</
div
>
</
div
>
<
div
class
=
"form-group"
>
@Html.LabelFor(
model
=
>
model.InvoiceDate, htmlAttributes: new { @
class
=
"control-label col-md-2"
})
<
div
class
=
"col-md-10"
>
@Html.EditorFor(
model
=
>
model.InvoiceDate, new {
htmlAttributes
=
new
{ @
class
=
"form-control"
} })
@Html.ValidationMessageFor(
model
=
>
model.InvoiceDate, "", new { @
class
=
"text-danger"
})
</
div
>
</
div
>
<
div
class
=
"form-group"
>
@Html.LabelFor(
model
=
>
model.OwnerClientIDFK, "OwnerClientIDFK", htmlAttributes: new { @
class
=
"control-label col-md-2"
})
<
div
class
=
"col-md-10"
>
@Html.DropDownList("OwnerClientIDFK", null, htmlAttributes: new { @
class
=
"form-control"
})
@Html.ValidationMessageFor(
model
=
>
model.OwnerClientIDFK, "", new { @
class
=
"text-danger"
})
</
div
>
</
div
>
<
div
class
=
"form-group"
>
<
h2
>
Invoice Lines
</
h2
>
<
hr
/>
@Html.ValidationSummary(true, "", new { @
class
=
"text-danger"
})
<
div
class
=
"row"
>
<
div
class
=
"col-md-8"
>
<
table
class
=
"table"
>
<
thead
>
<
tr
>
<
th
>
Item
</
th
>
<
th
>
Description
</
th
>
<
th
>
Qty
</
th
>
<
th
>
Unit Value
</
th
>
</
tr
>
</
thead
>
<
tbody
>
@for (int
i
=
0
; i
<
Model.InvoiceLines.Count
; i++)
{
<
tr
>
<
td
>
@Html.EditorFor(
x
=
>
x.InvoiceLines[i].ItemName, new {
htmlAttributes
=
new
{ @
class
=
"form-control"
} })
</
td
>
</
tr
>
}
</
tbody
>
</
table
>
</
div
>
</
div
>
</
div
>
<
div
class
=
"form-group"
>
<
div
class
=
"col-md-offset-2 col-md-10"
>
<
input
type
=
"submit"
value
=
"Save"
class
=
"btn btn-default"
/>
</
div
>
</
div
>
</
div
>
}
<
div
>
@Html.ActionLink("Back to List", "Index")
</
div
>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Any help appreciated. Thanks in advance.
Reply
Answers (
5
)
IIS Automatic Restart
checkbox problem