I have 2 model classes named Member & Envelope shown below where Member has a 1 to 1 relationship with Envelope:
namespace Mapping.Models
{
public class Member
{
[Key]
public int MemberId { get; set; }
[Required]
[Display(Name = "Mailing Name")]
[StringLength(250)]
public string? MemberMailingName { get; set; }
[Required]
[Display(Name = "Family Name")]
[StringLength(250)]
public string? MemberFamilyName { get; set; }
[Required]
[Display(Name = "Status")]
[StringLength(10)]
public string? MemberStatus { get; set; }
// Navigation Properties
public virtual Envelope? Envelope { get; set; }
}
public class Envelope
{
[Key]
public int EnvelopeId { get; set; }
[Required]
[Display(Name = "Envelope Number")]
public int EnvelopeNumber { get; set; }
}
}
When I pass the Member model to the Edit view, it recognizes that there is an Envelope associated with it.
I have 2 problems:
Below is the MembersController method for Edit and the Edit.cshtml that I'm using (Please don't judge the crappy HTML - I'll clean it all up once it works correctly!)
Thanks in Advance for any help with this!!
Edit Method in MembersController:
// GET: Members/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var member = await _context.Member.FindAsync(id);
if (member == null)
{
return NotFound();
}
return View(member);
}
Edit.cshtml:
@model StJosephMapping.Models.Member
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Member</h4>
<hr />
<div class="row">
<div class="col-md-12">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="MemberId" />
<span>
<table style="float: left;">
<tr>
<th style="width:25%;">
<label asp-for="MemberMailingName" class="control-label"></label>
</th>
<th style="width:25%;">
<label asp-for="MemberFamilyName" class="control-label"></label>
</th>
<th style="width:25%;">
<label asp-for="MemberStatus" class="control-label"></label>
</th>
</tr>
<tr>
<td>
<input asp-for="MemberMailingName" class="form-control" />
</td>
<td>
<input asp-for="MemberFamilyName" class="form-control" />
</td>
<td>
<input asp-for="MemberStatus" class="form-control" />
</td>
</tr>
<tr>
<td>
<span asp-validation-for="MemberMailingName" class="text-danger"></span>
</td>
<td>
<span asp-validation-for="MemberFamilyName" class="text-danger"></span>
</td>
<td>
<span asp-validation-for="MemberStatus" class="text-danger"></span>
</td>
</tr>
</table>
<table style="display: inline-block;">
<tr>
<td>
<div class="form-group" style="margin-top: 26px;">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</td>
</tr>
</table>
</span>
</form>
</div>
</div>
<br />
<h4>Envelope</h4>
<hr />
<div class="row">
<div class="col-md-12">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="MemberId" />
<span>
<table style="float: left;">
<tr>
<th style="width:25%;">
<label asp-for="Envelope.EnvelopeNumber" class="control-label"></label>
</th>
</tr>
<tr>
<td>
<input asp-for="Envelope.EnvelopeNumber" class="form-control" />
</td>
</tr>
<tr>
<td>
<span asp-validation-for="Envelope.EnvelopeNumber" class="text-danger"></span>
</td>
</tr>
</table>
<table style="display: inline-block;">
<tr>
<td>
<div class="form-group" style="margin-top: 26px;">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</td>
</tr>
</table>
</span>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
I can't display the EnvelopeNumber from the Envelope in Edit fields - it shows up blank
You can do this by using the Include
method in Entity Framework Core:
public async Task<IActionResult> Edit(int? id)
{
if (id == null || _context.Member == null)
{
return NotFound();
}
//var member = await _context.Member.FindAsync(id);
var member = await _context.Member.Include(a => a.Envelope).FirstOrDefaultAsync(a=>a.MemberId==id);
if (member == null)
{
return NotFound();
}
return View(member);
}
I want to be able to update the Envelope table when the user clicks Submit (There is a separate and Submit button for the Member and the Envelope).
You need to ensure that the EnvelopeId
is included in the form so that the controller can identify which Envelope
needs to be updated.
Change your Edit.cshtml like below:
<div class="row">
<div class="col-md-12">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="MemberId" />
<span>
<table style="float: left;">
<tr>
<th style="width:25%;">
<label asp-for="MemberMailingName" class="control-label"></label>
</th>
<th style="width:25%;">
<label asp-for="MemberFamilyName" class="control-label"></label>
</th>
<th style="width:25%;">
<label asp-for="MemberStatus" class="control-label"></label>
</th>
</tr>
<tr>
<td>
<input asp-for="MemberMailingName" class="form-control" />
</td>
<td>
<input asp-for="MemberFamilyName" class="form-control" />
</td>
<td>
<input asp-for="MemberStatus" class="form-control" />
</td>
</tr>
<tr>
<td>
<span asp-validation-for="MemberMailingName" class="text-danger"></span>
</td>
<td>
<span asp-validation-for="MemberFamilyName" class="text-danger"></span>
</td>
<td>
<span asp-validation-for="MemberStatus" class="text-danger"></span>
</td>
</tr>
</table>
<table style="display: inline-block;">
<tr>
<td>
<div class="form-group" style="margin-top: 26px;">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</td>
</tr>
</table>
</span>
</form>
</div>
</div>
<br />
<h4>Envelope</h4>
<hr />
<div class="row">
<div class="col-md-12">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<!-- change here -->
<input type="hidden" asp-for="Envelope.EnvelopeId" />
<span>
<table style="float: left;">
<tr>
<th style="width:25%;">
<label asp-for="Envelope.EnvelopeNumber" class="control-label"></label>
</th>
</tr>
<tr>
<td>
<input asp-for="Envelope.EnvelopeNumber" class="form-control" />
</td>
</tr>
<tr>
<td>
<span asp-validation-for="Envelope.EnvelopeNumber" class="text-danger"></span>
</td>
</tr>
</table>
<table style="display: inline-block;">
<tr>
<td>
<div class="form-group" style="margin-top: 26px;">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</td>
</tr>
</table>
</span>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Edit action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id,Member member)
{
if(member.MemberId!=0)
{
if (id != member.MemberId)
{
return NotFound();
}
if (ModelState.IsValid)
{
//edit the member
try
{
_context.Update(member);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MemberExists(member.MemberId))
{
return NotFound();
}
else
{
throw;
}
}
//do you stuff...
return RedirectToAction(nameof(Index));
}
}
else
{
//edit the envelope
if(member.Envelope!=null)
{
try
{
_context.Update(member.Envelope);
await _context.SaveChangesAsync();
}
catch (Exception)
{
throw;
}
return RedirectToAction(nameof(Index));
//do you stuff...
}
}
return View(member);
}