MVC4 forms that save to entity framework models - forms

I have the following course model created using EF code first:
public class Course
{
[Key]
public int CourseID { get; set; }
[StringLength(50)]
public string Name { get; set; }
[StringLength(200)]
public string Description { get; set; }
[StringLength(50)]
public string Author { get; set; }
public DateTime UploadDate { get; set; }
public DateTime ExpiryDate { get; set; }
public int ParticipationPoints { get; set; }
public string BlobURL { get; set; }
//1 to many relationship
public virtual ICollection<Audit> Audits { get; set; }
public virtual ICollection<Content> Contents { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual ICollection<Feedback> Feedbacks { get; set; }
public virtual ICollection<Keyword> Keywords { get; set; }
public virtual ICollection<Target> Targets { get; set; }
public virtual ICollection<CourseSection> CourseSections { get; set; }
//many to many relationship
public virtual ICollection<MetaLearningUser> MetaLearningUsers { get; set; }
}
In design mode I have the following HTML fields:
<form class="custom">
<fieldset>
<div class="row">
<div class="twelve columns">
<div class="row">
<div class="six columns">
<label>Course Title</label>
<input type="text">
</div>
<div class="six columns">
<label>Author</label>
<input type="text">
</div>
</div>
<div class="row">
<div class="six columns">
<label>Keywords</label>
<input type="text">
</div>
<div class="six columns">
<label>Metadata</label>
<input type="text">
</div>
</div>
<div class="row">
<div class="twelve columns">
<label>Description</label>
<textarea></textarea>
</div>
</div>
<div class="row">
<div class="six columns bottom20">
<label>Media type</label>
<div class="custom dropdown"> Select media type
<ul>
<li>Screencast</li>
<li>Podcast</li>
<li>Document</li>
<li>SCORM</li>
</ul>
</div>
</div>
<div class="six columns bottom20">
<label>Directory</label>
<div class="custom dropdown"> Select subject
<ul>
<li>Human Resources</li>
<li>IT Security</li>
<li>Corporate Governance</li>
<li>Health & Safety</li>
<li>Legal</li>
<li>IT Infrastructure</li>
<li>3rd Parties</li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="six columns">
<label>Start date</label>
<input type="date" class="datefield">
</div>
<div class="six columns">
<label>End date</label>
<input type="date" class="datefield">
</div>
</div>
</div>
</div>
Submit
</fieldset>
</form>
</div>
How can I save the data entered in the text boxes to the entity framework database when the submit button is pressed?

When you send in the model to the view, use something like
#using(Html.BeginForm("Index"))
{
#Html.TexboxFor(x => x.Name) // istead of <input type=text>
#Html.TextborFor(x => x.Description)
<input type="submit" value="Submit button"/>
}
to bind the model to the view, which in turn will make it post back when you click the submitt button.
In the controller you have something like
[HttpPost]
public ActionResult Index(CourseViewModel model) // because you'd want to use a
// view model and not the entity itself
{
// check if the model is valid
// maybe some more logic
db.SaveChanges();
return View(model);
}

Related

Model Binding with List of Objects Not Working

Model binding a List of objects is not working as expected.
When entering the OnPost method the UploadTransactions List is not null, but an empty list.
I have followed the instructions outlined here
I have been trying to figure this out for days now, I can't seem to wrap my head around why this is not working as expected.
Even some advice on how to debug what is being posted and why it is failing to bind to the property would be helpful. I can bind any other data as expected, but when I try to use a list of objects I am unable to get it to work.
public class UploadTransaction
{
public UploadTransaction()
{
}
public string Date { get; set; }
public string Amount { get; set; }
public string Type { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public string State { get; set; }
public string TransId { get; set; }
}
public class ViewUploadModel : PageModel
{
public BankscrapeDbContext BankscrapeDbContext { get; }
[BindProperty]
public List<UploadTransaction> UploadTransactions { get; set; }
public List<Transaction> Transactions { get; set; }
public ViewUploadModel(BankscrapeDbContext bankscrapeDbContext)
{
BankscrapeDbContext = bankscrapeDbContext;
}
public void OnGet()
{
Transactions = JsonConvert.DeserializeObject<List<Transaction>>(this.HttpContext.Session.GetString("UploadTransactions"));
}
public IActionResult OnPost()
{
}
}
<form method="post">
<div clss="container">
<table class="table table-striped">
<thead>
<tr>
<td>Date</td>
<td>Amount</td>
<td>Type</td>
<td>Description</td>
<td>Location</td>
<td>State</td>
<td>Transaction ID</td>
</tr>
</thead>
<tbody>
#for (var i = 0; i < Model.Transactions.Count; i++)
{
<tr>
<td><input class="form-control" type="text" aps-for="UploadTransactions[#i].Date" value="#Model.Transactions[i].Date" /></td>
<td><input class="form-control" type="text" aps-for="UploadTransactions[#i].Amount" value="#Model.Transactions[i].Amount" /></td>
<td><input class="form-control" type="text" aps-for="UploadTransactions[#i].Type" value="#Model.Transactions[i].Type" /></td>
<td><input class="form-control" type="text" aps-for="UploadTransactions[#i].Description" value="#Model.Transactions[i].Description" /></td>
<td><input class="form-control" type="text" aps-for="UploadTransactions[#i].Location" value="#Model.Transactions[i].Location" /></td>
<td><input class="form-control" type="text" aps-for="UploadTransactions[#i].State" value="#Model.Transactions[i].State" /></td>
<td><input class="form-control" type="text" aps-for="UploadTransactions[#i].TransId" value="#Model.Transactions[i].TransId" /></td>
</tr>
}
</tbody>
</table>
</div>
<div class="container">
<button class="btn btn-primary mt-3" type="submit" style="min-width:100%" id="button-submit">Upload</button>
</div>
</form>
Try to change aps-for="UploadTransactions[#i].xxx" with name="UploadTransactions[#i].xxx:
#for (var i = 0; i < Model.Transactions.Count; i++)
{
<tr>
<td><input class="form-control" type="text" name="UploadTransactions[#i].Date" value="#Model.Transactions[i].Date" /></td>
<td><input class="form-control" type="text" name="UploadTransactions[#i].Amount" value="#Model.Transactions[i].Amount" /></td>
<td><input class="form-control" type="text" name="UploadTransactions[#i].Type" value="#Model.Transactions[i].Type" /></td>
<td><input class="form-control" type="text" name="UploadTransactions[#i].Description" value="#Model.Transactions[i].Description" /></td>
<td><input class="form-control" type="text" name="UploadTransactions[#i].Location" value="#Model.Transactions[i].Location" /></td>
<td><input class="form-control" type="text" name="UploadTransactions[#i].State" value="#Model.Transactions[i].State" /></td>
<td><input class="form-control" type="text" name="UploadTransactions[#i].TransId" value="#Model.Transactions[i].TransId" /></td>
</tr>
}

How do I pass master id to detail foreign key?

I have a master-detail edit that doesn't work as it should.
TaBarHeader - master and TaBarBody - detail, have one-to-many relationship:
public partial class TaBarHeader
{
[Key]
public int Id { get; set; }
public string ListaOtf { get; set; }
public IEnumerable<TaBarBody> TaBarBodies { get; set; }
public IEnumerable<TaBarTelegrama> TaBarTelegramas { get; set; }
}
public partial class TaBarBody
{
[Key]
public int Id { get; set; }
public string Codstatie1 { get; set; }
public int BarHeaderId { get; set; }
[ForeignKey("BarHeaderId")]
public TaBarHeader BarHeaderFk { get; set; }
}
HeaderTelegrama/Details.cshtml:
#model TraficAlert.Models.ViewModels.HeaderTelegramaViewModel
<dt class="col-sm-2">
#Html.DisplayNameFor(model => model.TaBarHeader.ListaOtf)
</dt>
<dd class="col-sm-10">
#Html.DisplayFor(model => model.TaBarHeader.ListaOtf)
</dd>
(...)
<th>
#Html.DisplayNameFor(model => model.TaBarBody.Codstatie1)
</th>
#foreach (var item in Model.TaBarHeader.TaBarBodies)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Codstatie1)
</td>
<a asp-controller="BodyTelegrama" asp-action="Edit" asp-route-id="#item.Id">Edit</a>
BodyTelegrama/Edit.cshtml:
#model TraficAlert.Models.ViewModels.BodyTelegramaViewModel
#{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>TaBarBody</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.Codstatie1" class="control-label">Cod Statie 1</label>
<input asp-for="#Model.TaBarBody.Codstatie1" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.Codstatie1" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.Codstatie2" class="control-label">Cod Statie 2</label>
<input asp-for="#Model.TaBarBody.Codstatie2" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.Codstatie2" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.DtIniP" class="control-label">Data Ini P</label>
<input asp-for="#Model.TaBarBody.DtIniP" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.DtIniP" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.DtFinP" class="control-label">Data Fin P</label>
<input asp-for="#Model.TaBarBody.DtFinP" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.DtFinP" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.DtIniR" class="control-label">Data Ini R</label>
<input asp-for="#Model.TaBarBody.DtIniR" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.DtFinP" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.DtFinR" class="control-label">Data Fin R</label>
<input asp-for="#Model.TaBarBody.DtFinR" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.DtFinR" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.KmIni" class="control-label">Km Ini</label>
<input asp-for="#Model.TaBarBody.KmIni" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.KmIni" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.KmFin" class="control-label">Km Fin</label>
<input asp-for="#Model.TaBarBody.KmFin" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.KmFin" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.LiniaFir" class="control-label">Linia Fir</label>
<input asp-for="#Model.TaBarBody.LiniaFir" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.LiniaFir" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.NomImpactId" class="control-label">Impact</label>
<select asp-for="#Model.TaBarBody.NomImpactId" class="form-control" asp-items="ViewBag.NomImpactId"></select>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.NomAnulatId" class="control-label">Anulat</label>
<select asp-for="#Model.TaBarBody.NomAnulatId" class="form-control" asp-items="ViewBag.NomAnulatId"></select>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.MotivAnulare" class="control-label">Motiv Anulare</label>
<input asp-for="#Model.TaBarBody.MotivAnulare" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.MotivAnulare" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="#Model.TaBarBody.Ruta" class="control-label">Ruta</label>
<input asp-for="#Model.TaBarBody.Ruta" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.Ruta" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" asp-route-id="#ViewBag.TelegramaId" value="Save" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
BodyTelegramaController:
// GET
public IActionResult Edit(int id, int HeaderTelegramaId)
{
BodyTelegramaViewModel bodyTelegramaViewModel = new BodyTelegramaViewModel();
bodyTelegramaViewModel.TaBarBody = new TaBarBody();
bodyTelegramaViewModel.TaBarBody.BarHeaderFk = new TaBarHeader();
bodyTelegramaViewModel.TaBarBody = _unitofwork.BarBody.DetailsBarB(id);
bodyTelegramaViewModel.TaBarBody.BarHeaderFk = _unitofwork.BarHeader.DetailsBarHB(id);
ViewData["TelegramaId"] = HeaderTelegramaId;
if (bodyTelegramaViewModel.TaBarBody == null)
{
return NotFound();
}
ViewData["NomImpactId"] = new SelectList(_unitofwork.NomImpact.GetAll(), "Id", "Nume");
ViewData["NomAnulatId"] = new SelectList(_unitofwork.NomAnulat.GetAll(), "Id", "Nume");
return View(bodyTelegramaViewModel);
}
// POST
public IActionResult Edit(int id, BodyTelegramaViewModel bodyTelegramaViewModel)
{
if (id != bodyTelegramaViewModel.TaBarBody.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
bodyTelegramaViewModel.TaBarBody.BarHeaderId = id;
_unitofwork.BarBody.Update(bodyTelegramaViewModel.TaBarBody);
_unitofwork.Save();
}
catch (DbUpdateConcurrencyException)
{
if (!TaBarBodyExists(bodyTelegramaViewModel.TaBarBody.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(bodyTelegramaViewModel);
}
Everytime I edit a record, my foreign key - BarHeaderId - change its value to 0.
I have tried bodyTelegramaViewModel.TaBarBody.BarHeaderId = bodyTelegramaViewModel.TaBarHeader.Id; but I get the error 'Object reference not set to an instance of an object.'
How can I get the TaBarHeader.Id value and put it in TaBarBody.BarHeaderId?
Update:
ViewModels:
public class HeaderTelegramaViewModel
{
public TaBarHeader TaBarHeader { get; set; }
public IEnumerable<TaBarHeader> taBarHeader { get; set; }
public TaBarBody TaBarBody { get; set; }
public IEnumerable<TaBarBody> taBarBody { get; set; }
}
public class BodyTelegramaViewModel
{
public TaBarBody TaBarBody { get; set; }
public IEnumerable<TaBarBody> taBarBody { get; set; }
}
HeaderTelegramaController:
public IActionResult Details(int id)
{
HeaderTelegramaViewModel headerTelegramaViewModel = new HeaderTelegramaViewModel();
headerTelegramaViewModel.TaBarHeader = _unitofwork.BarHeaderRepository.DetailsBarHB(id);
if (headerTelegramaViewModel == null)
{
return NotFound();
}
return View(headerTelegramaViewModel);
}
BodyTelegramaController:
// GET
public IActionResult Edit(int id)
{
BodyTelegramaViewModel bodyTelegramaViewModel = new BodyTelegramaViewModel();
bodyTelegramaViewModel.TaBarBody = new TaBarBody();
bodyTelegramaViewModel.TaBarBody.BarHeaderFk = new TaBarHeader();
bodyTelegramaViewModel.TaBarBody = _unitofwork.BarBodyRepository.DetailsBarB(id);
bodyTelegramaViewModel.TaBarBody.BarHeaderFk = _unitofwork.BarHeaderRepository.DetailsBarHB(id);
return View(bodyTelegramaViewModel);
}
These are the methods DetailsBarB() and DetailsBarHB():
public TaBarBody DetailsBarB(int id)
{
return _db.TaBarBodies
.Include(t => t.BarHeaderFk)
.FirstOrDefault(m => m.Id == id);
}
public TaBarHeader DetailsBarHB(int id)
{
return _db.TaBarHeaders
.Include(x => x.TaBarBodies).ThenInclude(x => x.BarHeaderFk.CategoriaFk)
.FirstOrDefault(m => m.Id == id);
}
You can do following changes to get the TaBarHeader id.
In your Details View,change it to:
<a asp-controller="BodyTelegrama" asp-action="Edit" asp-route-id="#item.Id" asp-route-HeaderTelegramaId="#Model.TaBarHeader.Id">Edit</a>
In your Edit action,change it to:
public IActionResult Edit(int id,int HeaderTelegramaId)
{
BodyTelegramaViewModel bodyTelegramaViewModel = new BodyTelegramaViewModel();
bodyTelegramaViewModel.TaBarBody = new TaBarBody();
bodyTelegramaViewModel.TaBarBody.BarHeaderFk = new TaBarHeader();
bodyTelegramaViewModel.TaBarBody = _unitofwork.BarBodyRepository.DetailsBarB(id);
bodyTelegramaViewModel.TaBarBody.BarHeaderFk = _unitofwork.BarHeaderRepository.DetailsBarHB(id);
ViewData["TelegramaId"] = HeaderTelegramaId;
return View(bodyTelegramaViewModel);
}
[HttpPost]
public IActionResult Edit(int id, BodyTelegramaViewModel bodyTelegramaViewModel)
{
bodyTelegramaViewModel.TaBarBody.BarHeaderId = id;
_unitofwork.BarBodyRepository.Update(bodyTelegramaViewModel.TaBarBody);
_unitofwork.Save();
return View(bodyTelegramaViewModel);
}
Then in your Edit View,change it to:
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<input type="hidden" asp-for="#Model.TaBarBody.Id" />
<label asp-for="#Model.TaBarBody.Codstatie1" class="control-label">Cod Statie 1</label>
<input asp-for="#Model.TaBarBody.Codstatie1" class="form-control" />
<span asp-validation-for="#Model.TaBarBody.Codstatie1" class="text-danger"></span>
</div>
<div>
<input type="submit" asp-route-id="#ViewBag.TelegramaId" value="Save"/>
</div>
</form>
Then in your Edit post action,the id will be the TaBarHeader.Id.
Test Result:

CascadingParameter is null when trying to pull data from parent object

I am working on having a button setup that opens a blazored modal that allows a user to enter in the hours and minutes worked on a request, as well as adding comments. I started using the Blazored.Modal nuget package the [CascadingParameter] is used for closing or submitting the data in the modal. When looking through with a break point on I found that the
[CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; }
comes back NULL when I try to pass data in form the parent object. I have attached my code for my issue below. Thanks for your help and responses in advanced.
#using Logscan_Request.Shared
#using Logscan_Request.Pages.Modal
#using Logscan_Request.Shared.Tabs
<div class="card-header" #onclick="Expand">
<div class="row">
<div class="col">
<label><b>ORI:#RequestItem.ORI</b></label>
</div>
<div class="col">
<label><b>Agency Name:#RequestItem.AGENCY_NAME</b></label>
</div>
<div class="col">
<label><b>Requestor:#RequestItem.Request_LName, #RequestItem.Request_FName</b></label>
</div>
<div class="col">
<label><b>Date Submitted:#RequestItem.AddWhen</b></label>
</div>
<div class="col">
#if (RequestItem.Priority.Equals("Urgent"))
{
<label><b>Priority:
<span class="badge badge-danger">
<span class="oi oi-warning"></span> #RequestItem.Priority
</span>
</b></label>
}
else
{
<label>
<b>
Priority:
<span class="badge badge-success">
<span class="oi oi-bell"></span> #RequestItem.Priority
</span>
</b>
</label>
}
</div>
#if (RequestItem.Completed == 0)
{
<div class="col">
<span class="badge badge-warning">
<span class="oi oi-plus"></span> New Logscan
</span>
</div>
}
else
{
<div class="col">
<span class="badge badge-success">
<span class="oi oi-check"></span> Completed
</span>
</div>
}
</div>
</div>
<div class="card p-3 shadow #collapsed">
<div class="card p-3 shadow">
<div class="card-header bg-dark">
<label class="text-white">Agency Information</label>
</div>
<div class="card-body border-light">
<div class="row">
<div class="col">
<label>Agency Name: </label>
<p>#RequestItem.AGENCY_NAME</p>
</div>
<div class="col">
<label>ORI:</label>
<p>#RequestItem.ORI</p>
</div>
<div class="col">
<label>Address:</label>
<p>#RequestItem.ADDRESS</p>
</div>
</div>
</div>
</div>
<br />
<div class="card p-3 shadow">
<div class="card-header bg-dark">
<label class="text-white">Supervisor Information</label>
</div>
<div class="card-body">
<div class="row">
#if (string.IsNullOrEmpty(RequestItem.Supervisor_FName) && string.IsNullOrEmpty(RequestItem.Supervisor_LName))
{
}
else
{
<div class="col">
<label>Name: </label>
<p>#RequestItem.Supervisor_LName, #RequestItem.Supervisor_FName</p>
</div>
}
<div class="col">
<label>Phone:</label>
<p>#RequestItem.Supervisor_Phone</p>
</div>
<div class="col">
<label>Cell Phone:</label>
<p>#RequestItem.Cell_Phone</p>
</div>
#if (String.IsNullOrEmpty(RequestItem.Fax_Number))
{
}
else
{
<div class="col">
<label>Fax:</label>
<p>#RequestItem.Fax_Number</p>
</div>
}
</div>
</div>
</div>
<br />
<div class="card p-3 shadow">
<div class="card-header bg-dark">
<label class="text-white">Requestor Information</label>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<label>Title:</label>
<p>#RequestItem.Request_Title</p>
</div>
<div class="col">
<label>Name:</label>
<p>#RequestItem.Request_LName, #RequestItem.Request_FName</p>
</div>
<div class="col">
<label>Email:</label>
<p>#RequestItem.Email</p>
</div>
<div class="col">
<label>Phone/Ext:</label>
#if (String.IsNullOrEmpty(RequestItem.Extension))
{
string NoExtension = RequestItem.Phone_number;
<p>#NoExtension</p>
}
else
{
string AddExtension = RequestItem.Phone_number + " / " + RequestItem.Extension;
<p>#AddExtension</p>
}
</div>
</div>
</div>
</div>
<br />
<div class="card p-3 shadow">
<div class="card-header bg-dark">
<label class="text-white">Logscan Information</label>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<label>Time to be searched:</label>
<p>#RequestItem.Timeframe_To_Be_Searched</p>
</div>
<div class="col">
<label>Request Reason:</label>
<p>#RequestItem.Request_Reason</p>
</div>
<div class="col">
<label>Request Type:</label>
<p>#RequestItem.SearchType</p>
</div>
<div class="col">
<label>Criteria:</label>
<p>#RequestItem.Criteria</p>
</div>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-2 justify-content-start">
<button class="btn btn-secondary" #onclick="OpenReportDialog">View Report</button>
<button class="btn btn-secondary" #onclick="OpenAssignReport">Assign</button>
<ViewReportDialog #ref="ViewReportDialog" OnPrint="Print" OnClose="CloseDialog" RequestedItem="RequestItem" />
<PrintDialog #ref="PrintDialog" OnPrint="Print" OnClose="CloseDialog" />
#if (clicked == true)
{
<CascadingValue Value="RequestItem">
<Assign_Report inModel="RequestItem"></Assign_Report>
</CascadingValue>
}
</div>
</div>
</div>
Code Behind page
using Blazored.Modal.Services;
using Logscan_Request.Pages.Modal;
using LogscanRequest.Shared.Domain;
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Logscan_Request.Pages
{
public partial class LogscanRequestItem
{
[CascadingParameter] public IModalService Modal { get; set; }
[Parameter] public LogscanRequestModel RequestItem { get; set; }
public ViewReportDialog ViewReportDialog { get; set; }
public PrintDialog PrintDialog { get; set; }
public Assign_Report Assign_Report { get; set; } = new Assign_Report();
protected string collapsed { get; set; } = "collapse";
protected bool Expanded;
protected void Expand()
{
if (!Expanded)
{
Expanded = true;
collapsed = string.Empty;
}
else
{
Expanded = false;
collapsed = "collapse";
}
}
private void OpenReportDialog()
{
ViewReportDialog.Show();
}
async Task OpenAssignReport()
{
Assign_Report.Show();
}
private void CloseDialog()
{
StateHasChanged();
}
public void Print()
{
ViewReportDialog.Close();
PrintDialog.Show();
StateHasChanged();
}
}
}
Modal page code behind
using Blazored.Modal;
using Blazored.Modal.Services;
using LogscanRequest.Shared.Domain;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Logscan_Request.Pages.Modal
{
public partial class Assign_Report
{
//[Inject] IHttpContextAccessor HttpContext { get; set; }
[Parameter] public LogscanRequestModel requestMod { get; set; }
[CascadingParameter] public IModalService Modal { get; set; }
[CascadingParameter] BlazoredModalInstance BlazoredModal { get; set; }
private EditContext EditContext;
private bool ShowDialog { get; set; }
async Task Close()
{
ShowDialog = false;
StateHasChanged();
await BlazoredModal.CloseAsync(ModalResult.Ok(true));
}
async Task Cancel() => await BlazoredModal.CancelAsync();
protected override void OnInitialized()
{
ShowDialog = false;
//EditContext = new EditContext(RequestMod);
//RequestMod.ModifyBy = HttpContext.HttpContext.User.Identity.Name;
}
private async Task HandleValidSubmit()
{
}
public void Show()
{
Modal.Show<Assign_Report>();
}
}
}
Error: System.InvalidOperationException: Object of type
'Logscan_Request.Pages.Modal.Assign_Report' does not have a property
matching the name 'Assign_Report'. at
Microsoft.AspNetCore.Components.Reflection.ComponentProperties.ThrowForUnknownIncomingParameterName(Type
targetType, String parameterName) at
Microsoft.AspNetCore.Components.Reflection.ComponentProperties.SetProperties(ParameterView&
parameters, Object target) at
Microsoft.AspNetCore.Components.ComponentBase.SetParametersAsync(ParameterView
parameters) at
Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView
parameters) at
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext&
diffContext, Int32 frameIndex) at
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext&
diffContext, Int32 frameIndex) at
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext&
diffContext, Int32 newFrameIndex) at
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext&
diffContext, Int32 newFrameIndex) at
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext&
diffContext, Int32 newFrameIndex) at
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext&
diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32
newStartIndex, Int32 newEndIndexExcl) at
Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer
renderer, RenderBatchBuilder batchBuilder, Int32 componentId,
ArrayRange1 oldTree, ArrayRange1 newTree) at
Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder
batchBuilder, RenderFragment renderFragment) at
Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry
renderQueueEntry) at
Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

Set value Entity Framework Core during OnGet

I thought this would be simple...
If I want to force a value to a column/filed before the page loads, how do I do that?
Here's the lines from the Model:
[DataType(DataType.Currency)]
[Column(TypeName = "money")]
[Display(Name = "Contract Value")]
public decimal? ContractValue { get; set; } = 0m;
[DataType(DataType.Currency)]
[Column(TypeName = "money")]
[Display(Name = "Contract Expended")]
public decimal? ContractValueExpended { get; set; } = 0m;
And, here's what I tried using Fluent API.
modelBuilder.Entity<Contract>()
.Property(e => e.ContractValue)
.HasDefaultValue(0);
modelBuilder.Entity<Contract>()
.Property(e => e.ContractValueExpended)
.HasDefaultValue(0);
My bad. Here is create.cshtml.cs
public class CreateModel : GlobalPageModel
{
private readonly TawdryIndustries.Data.CompanyContext _context;
public CreateModel(TawdryIndustries.Data.CompanyContext context)
{
_context = context;
}
public IActionResult OnGet()
{
PopulateEmployeeNamesSelectList(_context);
PopulateCustomerNamesSelectList(_context);
return Page();
}
[BindProperty]
public Contract Contract { get; set; }
public async Task<IActionResult> OnPostAsync()
{
var emptyContract = new Contract();
if (await TryUpdateModelAsync<Contract>(
emptyContract,
"Contract",
c => c.ContractID,
c => c.ContractNumber,
c => c.ContractName,
c => c.CustomerID,
c => c.ContractAwardDate,
c => c.ContractBegDate,
c => c.ContractEndDate,
c => c.ContractValue,
c => c.ContractValueExpended,
c => c.ContractManagerID))
{
_context.Contracts.Add(emptyContract);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
PopulateEmployeeNamesSelectList(_context, emptyContract.ContractManagerID);
PopulateCustomerNamesSelectList(_context, emptyContract.CustomerID);
return Page();
}
And, here is the razor page (create.cshtml):
#page
#model TawdryIndustries.Pages.Contracts.CreateModel
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Contract</h4>
<hr />
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<table class="table">
<tr>
<td>
<label asp-for="Contract.CustomerID" class="control-label"></label>
<select asp-for="Contract.CustomerID" class="form-control"
asp-items="#Model.CustomerNameSL">
<option value="">-- Select Customer --</option>
</select>
<span asp-validation-for="Contract.CustomerID" class="text-danger"></span>
</td>
<td>
<label asp-for="Contract.ContractNumber" class="control-label"></label>
<input asp-for="Contract.ContractNumber" class="form-control" />
<span asp-validation-for="Contract.ContractNumber" class="text-danger"></span>
</td>
<td>
<label asp-for="Contract.ContractName" class="control-label"></label>
<input asp-for="Contract.ContractName" class="form-control" />
<span asp-validation-for="Contract.ContractName" class="text-danger"></span>
</td>
</tr>
<tr>
<td>
<label asp-for="Contract.ContractAwardDate" class="control-label"></label>
<input asp-for="Contract.ContractAwardDate" class="form-control" />
<span asp-validation-for="Contract.ContractAwardDate" class="text-danger"></span>
</td>
<td>
<label asp-for="Contract.ContractBegDate" class="control-label"></label>
<input asp-for="Contract.ContractBegDate" class="form-control" />
<span asp-validation-for="Contract.ContractBegDate" class="text-danger"></span>
</td>
<td>
<label asp-for="Contract.ContractEndDate" class="control-label"></label>
<input asp-for="Contract.ContractEndDate" class="form-control" />
<span asp-validation-for="Contract.ContractEndDate" class="text-danger"></span>
</td>
</tr>
<tr>
<td>
<label asp-for="Contract.ContractValue" class="control-label"></label>
<input asp-for="Contract.ContractValue" class="form-control" />
<span asp-validation-for="Contract.ContractValue" class="text-danger"></span>
</td>
<td>
<label asp-for="Contract.ContractValueExpended" class="control-label"></label>
<input asp-for="Contract.ContractValueExpended" class="form-control" />
<span asp-validation-for="Contract.ContractValueExpended" class="text-danger"></span>
</td>
<td>
<label asp-for="Contract.ContractManagerID" class="control-label"></label>
<select asp-for="Contract.ContractManagerID" class="form-control"
asp-items="#Model.EmployeeNameSL">
<option value="">-- Select Manager --</option>
</select>
<span asp-validation-for="Contract.ContractManagerID" class="text-danger"></span>
</td>
</tr>
<tr>
<td>
<input type="submit" value="Create" class="btn btn-primary" />
</td>
</tr>
</table>
</form>
<div>
<a asp-page="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
However, when the page is displayed (in create specifically), both of those fields are still blank. I want to force both fields to 0 when a new contract is created before the page loads.
For that matter, is there any way to set a value for a variable before a page loads?
In ASP.NET I would
<html>
<head></head>
<body>
<asp:textbox id="mytext" runat="server"></asp:textbox>
</body>
and:
protected void Page_Load(object sender, EventArgs e)
{
string somevar = "This is a test";
mytext.Text = somevar;
}
And the text box would contain "This is a test" when the page was displayed.
What is the equivalent in EF Core?
Thanks,
John

Why is the object passed to Delete action empty?

I've got a basic ASP.NET MVC 2 application. I've got adding and editing rows working just fine, but deleting won't work. The Delete view gets the correct record on the GET, but when posting back, the parameter that gets passed is empty, as in CategoryID = 0, all empty values. Because of that, no object is found to be deleted from the database and an exception is thrown. How can I get the correct Category to be passed to the HttpPost Delete action?
Here's what I've got in the controller:
public ActionResult Delete(int id)
{
return View(_categoryRespository.Get(id));
}
[HttpPost]
public ActionResult Delete(Category categoryToDelete)
{
try
{
_categoryRespository.Delete(categoryToDelete);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
This is the Delete view, which as I said correctly displays the data on the GET:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVCApp.Models.Category>" %>
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>Fields</legend>
<div class="display-label">CategoryID</div>
<div class="display-field"><%: Model.CategoryID %></div>
<div class="display-label">SectionName</div>
<div class="display-field"><%: Model.SectionName %></div>
<div class="display-label">CategoryName</div>
<div class="display-field"><%: Model.CategoryName %></div>
<div class="display-label">Content</div>
<div class="display-field"><%: Model.Content %></div>
</fieldset>
<% using (Html.BeginForm()) { %>
<p>
<input type="submit" value="Delete" /> |
<%: Html.ActionLink("Back to List", "Index") %>
</p>
<% } %>
Your form is not actually POSTing anything. You can add a hidden input with CategoryID, and then create a static Delete method in your repository that will accept CategoryID as a parameter (or instantiate a category by CategoryID and then call your existing Delete method).
Controller
public ActionResult Delete(int id)
{
return View(_categoryRespository.Get(id));
}
[HttpPost]
public ActionResult Delete(int categoryID)
{
try
{
_categoryRespository.Delete(categoryID);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
View
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<fieldset>
<legend>Fields</legend>
<div class="display-label">CategoryID</div>
<div class="display-field"><%: Model.CategoryID %></div>
<div class="display-label">SectionName</div>
<div class="display-field"><%: Model.SectionName %></div>
<div class="display-label">CategoryName</div>
<div class="display-field"><%: Model.CategoryName %></div>
<div class="display-label">Content</div>
<div class="display-field"><%: Model.Content %></div>
</fieldset>
<% using (Html.BeginForm()) { %>
<p>
<input type="hidden" name="categoryID" value="<%: Model.CategoryID %>" />
<input type="submit" value="Delete" /> |
<%: Html.ActionLink("Back to List", "Index") %>
</p>
<% } %>