Out of the 4 tables that I have, 3 contain similar(client,policyno,policytype..) fields but with different data. The other table, however, has very different fields(client,sex,telephone,dob..). I have a search box in my view that makes use of the telephone number to display related records from all the 3 tables. Unfortunately, I am not able to handle the fields of the fourth table. Keeps returning the error
System.IndexOutOfRangeException: 'PolicyNo'
My Model:
public class TableModels
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Client { get; set; }
public string PolicyNo { get; set; }
public short? PolicyType { get; set; }
public string Telephone { get; set; }
//Health
public DateTime? DOB { get; set; }
public string Sex { get; set; }
public string DepMemberNumber { get; set; }
protected TableModels ReadValue(SqlDataReader reader)
{
TableModels obj = new TableModels();
if (reader["ID"] != DBNull.Value)
{
obj.ID = (int)reader["ID"];
}
if (reader["Client"] != DBNull.Value)
{
obj.Client = (string)reader["Client"];
}
if (reader["PolicyNo"] != DBNull.Value)
{
obj.PolicyNo = (string)reader["PolicyNo"];
}
if (reader["PolicyType"] != DBNull.Value)
{
obj.PolicyType = (short)reader["PolicyType"];
}
The error is returned on the Protected TableModel class.
Any advice would be appreciated
View:
#model IEnumerable
#foreach (var item in Model.OrderByDescending(m => m.Client))
{
<tr>
<td>
#Html.DisplayFor(modelitem => item.Client)
</td>
<td>
#Html.DisplayFor(modelitem => item.Telephone)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id = item.Telephone })
</td>
</tr>
}
Controller:
public ActionResult Details(string id)
{
using (MainContext db = new MainContext())
{
if (id == null)
{
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
}
List<SingleView> x1 = db.SingleViews.Where(a => a.Telephone == id).ToList();
List<SingleViewM> x2 = db.SingleViewMs.Where(a => a.Telephone == id).ToList();
List<SingleViewWst> x3 = db.SingleViewWsts.Where(a => a.Telephone == id).ToList();
List<PensionsView> x4 = db.PensionsViews.Where(a => a.Telephone == id).ToList();
List<Health> x5 = db.Health.Where(a => a.Telephone == id).ToList();
SingleModel objview = new SingleModel();
objview.USSD = x1;
objview.Mombasa = x2;
Related
I am still currently debugging the system becauae it seems to load all the data. My system has 4218 records. I have successfully used the Skip and Take in the system but the problem is that it only loads the first 10 records. How to call the other records? I want to do the Server Side Pagination.
This is the entity class:
public List<NonconformingServiceModel> GetAllNSIssue(int UserID, int pageNumber = 1)
{
using (SIRManagementSystemEntities _entities = new SIRManagementSystemEntities())
{
NonconformingServiceModel NSModel = new NonconformingServiceModel();
var date1 = new DateTime(2000, 1, 1, 1, 0, 0);
List<NonconformingServiceModel> result = new List<NonconformingServiceModel>();
var userData = (from _user in _entities.Administrators where _user.UserID == UserID select _user).FirstOrDefault();
if (userData != null)
{
if (userData.UserType == 1 || userData.UserType == 0 || userData.UserID == 38)
{
result = (from _NSDetails in _entities.NonconformingServices
join _creator in _entities.Administrators on _NSDetails.CreatedBy equals _creator.UserID
join _SIRDetails in _entities.SIR_InitialDetail on _NSDetails.NS_ID equals _SIRDetails.NSCCRefID into _sir
from _SIRDetails in _sir.DefaultIfEmpty()
select new NonconformingServiceModel
{
ID = _NSDetails.NS_ID,
Type = _NSDetails.Type,
Category = _NSDetails.Category,
Reason = _NSDetails.Reason,
Remarks = _NSDetails.Remarks,
ModeThru = _NSDetails.Mode,
DateDelivered = _NSDetails.DateDelivered,
LoadingDate = _NSDetails.LoadingDate,
DateIssue = _NSDetails.DateIssue,
Origin = _NSDetails.Origin,
Destination = _NSDetails.Destination,
CartonNumber = _NSDetails.CartonNumber,
ShipmentNumber = _NSDetails.ShipmentNumber,
ShipperName = _NSDetails.ShipperName,
ConsigneeName = _NSDetails.ConsigneeName,
Address = _NSDetails.Address,
NSGroup = _NSDetails.NSGroup,
NSCode = _NSDetails.NSCode,
OtherType = _NSDetails.OtherType,
CreatedByID = _NSDetails.CreatedBy,
CreatedByName = _creator.FirstName + " " + _creator.LastName,
SIRCode = _SIRDetails.Code == null ? "" : _SIRDetails.Code,
SIRDateIssue = _SIRDetails.IssueDate == null ? date1 : _SIRDetails.IssueDate,
SIRDueDate = _SIRDetails.DueDate == null ? date1 : _SIRDetails.DueDate,
Status = _SIRDetails.Code == null ? 0 : _SIRDetails.Status
}).ToList();
}
else
{
result = (from _creator in _entities.Administrators
join _NSDetails in _entities.NonconformingServices on _creator.UserID equals _NSDetails.CreatedBy
join _mapping in _entities.CCNSDEPTMappings on _NSDetails.NSCode equals _mapping.NSCode
join _SIRDetails in _entities.SIR_InitialDetail on _NSDetails.NS_ID equals _SIRDetails.NSCCRefID into _sir
from _SIRDetails in _sir.DefaultIfEmpty()
where _creator.Department == userData.Department || _mapping.ConcernDeptID == userData.Department || _creator.Department == userData.SecondDept || _mapping.ConcernDeptID == userData.SecondDept
select new NonconformingServiceModel
{
ID = _NSDetails.NS_ID,
Type = _NSDetails.Type,
Category = _NSDetails.Category,
Reason = _NSDetails.Reason,
Remarks = _NSDetails.Remarks,
ModeThru = _NSDetails.Mode,
DateDelivered = _NSDetails.DateDelivered,
LoadingDate = _NSDetails.LoadingDate,
DateIssue = _NSDetails.DateIssue,
Origin = _NSDetails.Origin,
Destination = _NSDetails.Destination,
CartonNumber = _NSDetails.CartonNumber,
ShipmentNumber = _NSDetails.ShipmentNumber,
ShipperName = _NSDetails.ShipperName,
ConsigneeName = _NSDetails.ConsigneeName,
Address = _NSDetails.Address,
NSGroup = _NSDetails.NSGroup,
NSCode = _NSDetails.NSCode,
OtherType = _NSDetails.OtherType,
CreatedByID = _NSDetails.CreatedBy,
CreatedByName = _creator.FirstName + " " + _creator.LastName,
SIRCode = _SIRDetails.Code == null ? "" : _SIRDetails.Code,
SIRDateIssue = _SIRDetails.IssueDate == null ? date1 : _SIRDetails.IssueDate,
SIRDueDate = _SIRDetails.DueDate == null ? date1 : _SIRDetails.DueDate,
Status = _SIRDetails.Code == null ? 0 : _SIRDetails.Status
}).ToList();
// var _result = (List<NonconformingServiceModel>)result.GroupBy(x => x.NSCode).Select(x => x.FirstOrDefault()).ToList().Skip((pageNumber - 1) * 10).Take(10);
}
var _result = result.GroupBy(x => x.NSCode).Select(x => x.FirstOrDefault()).ToList().Skip((pageNumber - 1) * 10).Take(10);
foreach (var item in _result)
{
if (item.Status == null || item.Status == 0)
{
if (item.SIRCode != "")
{
DateTime dueDate = item.SIRDueDate.Value;
DateTime now = DateTime.Now;
if (now.Date > dueDate.Date)
{
item.FormatIssueDate = "late";
}
else
{
item.FormatIssueDate = "not";
}
}
else
{
item.SIRCode = "";
item.SIRDateIssue = null;
item.SIRDueDate = null;
item.Status = 0;
}
}
else
{
item.SIRID = (from _sirDet in _entities.SIR_InitialDetail where _sirDet.Code == item.SIRCode select _sirDet.sirID).FirstOrDefault();
item.SubmissionDate = (from _sirDet in _entities.SIR_InitialDetail where _sirDet.sirID == item.SIRID select _sirDet.SubmissionDate).FirstOrDefault();
item.CEDueDate = (from _sirCA in _entities.SIR_CorrectActDetail where _sirCA.Cor_SIRID == item.SIRID select _sirCA.CEDueDate).FirstOrDefault();
item.FormatIssueDate = "submitted";
}
item.TypeName = (from _type in _entities.DDNSTypes where _type.TypeID == item.Type select _type.Label).FirstOrDefault();
if (item.Type == 19)
{
item.TypeName = item.OtherType;
}
item.CategoryName = (from _cat in _entities.DDCategories where _cat.SIRCAT_ID == item.Category select _cat.Label).FirstOrDefault();
var deptArray = (from _mapping in _entities.CCNSDEPTMappings
join _dept in _entities.Departments on _mapping.ConcernDeptID equals _dept.DeptID
where _mapping.NSCode == item.NSCode
select _dept.DeptID).ToList();
var deptCode = (from _mapping in _entities.CCNSDEPTMappings
join _dept in _entities.Departments on _mapping.ConcernDeptID equals _dept.DeptID
where _mapping.NSCode == item.NSCode
select _dept.DeptCode).ToList();
item.ConcernedDeptArray = deptArray;
item.ConcernedDeptName = deptCode;
item.Company = (from _user in _entities.Administrators
join _dept in _entities.Departments on _user.Department equals _dept.DeptID
where _user.UserID == item.CreatedByID select _dept.Company).FirstOrDefault();
}
return _result.ToList();
}
return null;
}
}
This is the view model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SIMS.Model.Models
{
public class NonconformingServiceModel
{
public int ID { get; set; }
public byte Type { get; set; }
public string TypeName { get; set; }
public string OtherType { get; set; }
public byte Category { get; set; }
public string CategoryName { get; set; }
public string OtherCategory { get; set; }
public string Reason { get; set; }
public string Remarks { get; set; }
public string ModeThru { get; set; }
public DateTime? DateDelivered { get; set; }
public DateTime? LoadingDate { get; set; }
public DateTime DateIssue { get; set; }
public string ConcernedDeptString { get; set; }
public List<int> ConcernedDeptArray { get; set; }
public List<string> ConcernedDeptName { get; set; }
public string Origin { get; set; }
public string Destination { get; set; }
public string CartonNumber { get; set; }
public string ShipmentNumber { get; set; }
public string ShipperName { get; set; }
public string ConsigneeName { get; set; }
public string Address { get; set; }
public string NSGroup { get; set; }
public int CreatedByID { get; set; }
public string CreatedByName { get; set; }
public int CreatedByDept { get; set; }
public int UserType { get; set; }
public string NSCode { get; set; }
public byte? Status { get; set; }
public int? SIRID { get; set; }
public string SIRCode { get; set; }
public DateTime? SIRDateIssue { get; set; }
public DateTime? SIRDueDate { get; set; }
public DateTime? SubmissionDate { get; set; }
public DateTime? CEDueDate { get; set; }
public DateTime? DetectionDate { get; set; }
public string FormatIssueDate { get; set; }
public int UserID { get; set; }
public int? Company { get; set; }
}
}
This is the controller class:
public ActionResult GetAllNSLogDetails(int UserID)
{
JsonResult _json = new JsonResult();
NonconformingServiceManager _NSManager = new NonconformingServiceManager();
_json.Data = _NSManager.GetAllNSIssue(UserID);
_json.MaxJsonLength = Int32.MaxValue;
return _json;
}
This is the view:
<!-- Begin Page Content -->
<div class="container-fluid">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">Dashboard</li>
<li class="breadcrumb-item active" aria-current="page">Nonconforming Service</li>
</ol>
</nav>
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Nonconforming Services Log</h6>
<div class="text-right">
<button type="button" class="btn btn-outline-info" onclick="window.location.reload();">Show All Data</button>
<button type="button" data-toggle="modal" data-target=".modal-filter-table" class="btn btn-outline-info"><i class="fas fa-filter"></i>Sort by</button>
<button type="button" onclick="CreateNewConcern()" class="btn btn-outline-primary"><i class="far fa-plus-square"></i> Create New NS</button>
</div>
</div>
<div class="card-body">
<div class="card-body table-responsive">
<table id="NonconformingServiceLogGrid" class="table table-hover" style="width:100%">
<thead>
<tr>
<th>Date Created</th>
<th>NS Code</th>
<th>SIR Code</th>
<th>Date Issue</th>
<th>Due Date</th>
<th>Submission Date</th>
<th>Type</th>
<th>Category</th>
<th>Concerned Dept.</th>
<th>SIR Status</th>
<th>CE Due Date</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date Created</th>
<th>NS Code</th>
<th>SIR Code</th>
<th>Date Issue</th>
<th>Due Date</th>
<th>Submission Date</th>
<th>Type</th>
<th>Category</th>
<th>Concerned Dept.</th>
<th>SIR Status</th>
<th>CE Due Date</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
All answers will be appreciated.
You required one Pagination Class as per below example:
Response.cs
public class Response<T>
{
public Response()
{
}
public Response(T data)
{
Succeeded = true;
Message = string.Empty;
Errors = null;
Data = data;
}
public T Data { get; set; }
public bool Succeeded { get; set; }
public string[] Errors { get; set; }
public string Message { get; set; }
}
Second class is PageResponse.cs
public class PagedResponse<T> : Response<T>
{
public int PageNumber { get; set; }
public int PageSize { get; set; }
public int TotalPages { get; set; }
public int TotalRecords { get; set; }
public int TotalFilteredRecords { get; set; }
public PagedResponse(T data, int pageNumber, int pageSize)
{
PageNumber = pageNumber;
PageSize = pageSize;
Data = data;
Message = null;
Succeeded = true;
Errors = null;
}
}
In controller you just need to fetch the data like below:
[HttpGet]
public async Task<IActionResult> GetAllDetailAsync(int pageNumber)
{
int pageSize=10;
var pagedData = await _Service.GetData(pageNumber, pageSize);
PagedResponse<List<MyModel>> pagedResponse = new(pagedData, pageNumber, pageSize);
pagedResponse.TotalRecords = await _Service.GetTotalRecords();
int totalPages = pagedResponse.TotalRecords / pagedResponse.PageSize;
if ((pagedResponse.TotalRecords % pagedResponse.PageSize) != 0)
{
totalPages++;
}
pagedResponse.TotalPages = totalPages;
return Ok(pagedResponse);
}
i'm getting a issue in my program.
In the Index View from the "Emprestimo" controller i'm trying to get the name from the book from the "Livro" class, but when i put the following it only gives me a blank space:
#Html.DisplayFor(modelItem => item.Livro.Titulo)
I Have a foreign key from "Livro" (book) inside the "Emprestimo", and when i put the following, i get the ID from the book, but far i know, i can't put a string as FK:
#Html.DisplayFor(modelItem => item.LivroId)
I tried some variations but i couldn't get the expected result. It's not a list inside the "Emprestimo", because in one loan can exist only one book.
Here's the complete code and the github link from the project if you want to take a better look:
https://github.com/KaioMartins/PersonalLibrary
Usuario.cs
namespace PersonalLibrary.Models
{
public class Usuario
{
public int UsuarioId { get; set; }
[Display(Name = "Usuário")]
public string Nome { get; set; }
[Display(Name = "E-mail")]
public string Email { get; set; }
[Display(Name = "Senha")]
public string Senha { get; set; }
public virtual List<Livro> Livros { get; set; }
public virtual List<Emprestimo> Emprestimos { get; set; }
public virtual List<Autor> Autor { get; set; }
}
}
Livro.cs
namespace PersonalLibrary.Models
{
public class Livro
{
public int LivroId { get; set; }
[Required(ErrorMessage = "Digite o nome do Livro")]
[MaxLength(60)]
[Display(Name = "Livro")]
public string Titulo { get; set; }
[Required(ErrorMessage = "Digite o ISBN")]
[MaxLength(60)]
[Display(Name = "ISBN")]
public string ISBN { get; set; }
[Required(ErrorMessage = "Digite a Data da Compra do Livro")]
[Display(Name = "Data da Compra")]
public DateTime DataCompra { get; set; }
[Display(Name = "Leitura Concluída")]
public Boolean StatusLido { get; set; }
[Required(ErrorMessage = "Cadastre um Autor antes de Cadastrar um Livro")]
[Display(Name = "Autor")]
public int AutorId { get; set; }
[ForeignKey("AutorId")]
public virtual Autor Autor { get; set; }
[Display(Name = "Usuário")]
public int UsuarioId { get; set; }
[ForeignKey("UsuarioId")]
public virtual Usuario Usuario { get; set; }
}
}
Emprestimo.cs
namespace PersonalLibrary.Models
{
public class Emprestimo
{
public int EmprestimoId { get; set; }
[Display(Name = "Emprestado")]
public Boolean Emprestado { get; set; }
[Display(Name = "Emprestado para: ")]
public string PessoaEmprestimo { get; set; }
[Display(Name = "Data do Empréstimo")]
public DateTime DataEmprestimo { get; set; }
[Display(Name = "Data da Devolução")]
public DateTime DataDevolucao { get; set; }
[Display(Name = "Livro")]
public int LivroId { get; set; }
[ForeignKey("LivroId")]
public virtual Livro Livro { get; set; }
[Display(Name = "Usuário")]
public int UsuarioId { get; set; }
[ForeignKey("UsuarioId")]
public virtual Usuario Usuario { get; set; }
}
}
EmprestimoController.cs
namespace PersonalLibrary.Controllers
{
public class EmprestimoController : Controller
{
private LibraryContext db = new LibraryContext();
// GET: Emprestimo
[AuthFilter]
public ActionResult Index()
{
using(LibraryContext ctx = new LibraryContext())
{
Usuario user = (Usuario)Session["usuario"];
int id = user.UsuarioId;
List<Emprestimo> lista = ctx.Emprestimo.Where(c => c.UsuarioId == id).ToList();
return View(lista);
}
//var emprestimo = db.Emprestimo.Include(e => e.Titulo).Include(e => e.Usuario);
//return View(emprestimo.ToList());
}
// GET: Emprestimo/Details/5
[AuthFilter]
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Emprestimo emprestimo = db.Emprestimo.Find(id);
if (emprestimo == null)
{
return HttpNotFound();
}
return View(emprestimo);
}
// GET: Emprestimo/Create
[AuthFilter]
public ActionResult Create()
{
using (LibraryContext ctx = new LibraryContext())
{
Usuario u = (Usuario)Session["usuario"];
ViewBag.LivroId = new SelectList(db.Livro.Where(c => c.UsuarioId == u.UsuarioId), "LivroId", "Titulo");
return View();
}
}
// POST: Emprestimo/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
[AuthFilter]
public ActionResult Create([Bind(Include = "EmprestimoId,Emprestado,PessoaEmprestimo,DataEmprestimo,DataDevolucao,LivroId,UsuarioId")] Emprestimo emprestimo)
{
using (LibraryContext ctx = new LibraryContext())
{
if (ModelState.IsValid)
{
Usuario u = Session["usuario"] as Usuario;
emprestimo.UsuarioId = u.UsuarioId;
db.Emprestimo.Add(emprestimo);
db.SaveChanges();
ViewBag.LivroId = new SelectList(ctx.Usuario.Where(c => c.UsuarioId == u.UsuarioId));
return RedirectToAction("Index");
}
//ViewBag.LivroId = new SelectList(db.Livro, "LivroId", "Titulo", emprestimo.LivroId);
return View(emprestimo);
}
}
// GET: Emprestimo/Edit/5
[AuthFilter]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Emprestimo emprestimo = db.Emprestimo.Find(id);
if (emprestimo == null)
{
return HttpNotFound();
}
using (LibraryContext ctx = new LibraryContext())
{
Usuario u = (Usuario)Session["usuario"];
ViewBag.LivroId = new SelectList(db.Livro.Where(c => c.UsuarioId == u.UsuarioId), "LivroId", "Titulo");
return View(emprestimo);
}
//ViewBag.LivroId = new SelectList(db.Livro, "LivroId", "Titulo", emprestimo.LivroId);
//ViewBag.UsuarioId = new SelectList(db.Usuario, "UsuarioId", "Nome", emprestimo.UsuarioId);
//return View(emprestimo);
}
// POST: Emprestimo/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
[AuthFilter]
public ActionResult Edit([Bind(Include = "EmprestimoId,Emprestado,PessoaEmprestimo,DataEmprestimo,DataDevolucao,LivroId,UsuarioId")] Emprestimo emprestimo)
{
if (ModelState.IsValid)
{
Usuario u = Session["usuario"] as Usuario;
emprestimo.UsuarioId = u.UsuarioId;
db.Entry(emprestimo).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.LivroId = new SelectList(db.Livro, "LivroId", "Titulo", emprestimo.LivroId);
ViewBag.UsuarioId = new SelectList(db.Usuario, "UsuarioId", "Nome", emprestimo.UsuarioId);
return View(emprestimo);
}
// GET: Emprestimo/Delete/5
[AuthFilter]
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Emprestimo emprestimo = db.Emprestimo.Find(id);
if (emprestimo == null)
{
return HttpNotFound();
}
return View(emprestimo);
}
// POST: Emprestimo/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
[AuthFilter]
public ActionResult DeleteConfirmed(int id)
{
Emprestimo emprestimo = db.Emprestimo.Find(id);
db.Emprestimo.Remove(emprestimo);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Index.cshtml (Emprestimo)
#model IEnumerable<PersonalLibrary.Models.Emprestimo>
#{
ViewBag.Title = "Livros Emprestados";
}
<p>
#Html.ActionLink("Cadastrar Empréstimo", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Livro.Titulo)
</th>
<th>
#Html.DisplayNameFor(model => model.Emprestado)
</th>
<th>
#Html.DisplayNameFor(model => model.PessoaEmprestimo)
</th>
<th>
#Html.DisplayNameFor(model => model.DataEmprestimo)
</th>
<th>
#Html.DisplayNameFor(model => model.DataDevolucao)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.LivroId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Emprestado)
</td>
<td>
#Html.DisplayFor(modelItem => item.PessoaEmprestimo)
</td>
<td>
#Html.DisplayFor(modelItem => item.DataEmprestimo)
</td>
<td>
#Html.DisplayFor(modelItem => item.DataDevolucao)
</td>
<td>
#Html.ActionLink("Editar", "Edit", new { id=item.EmprestimoId }) |
#Html.ActionLink("Detalhes", "Details", new { id=item.EmprestimoId }) |
#Html.ActionLink("Excluir", "Delete", new { id=item.EmprestimoId })
</td>
</tr>
}
</table>
That is because the Livro property is virtual, therefore it will not be loaded unless you access the property or load it like this:
List<Emprestimo> lista = ctx.Emprestimo.Include(x => x.Livro).Where(c => c.UsuarioId == id).ToList();
This is called eager loading. By default EF is configured for lazy loading.
On your Emprestimo.Edit controller action try loading the Livro entity:
Emprestimo emprestimo = db.Emprestimo.Find(id);
if (emprestimo == null)
{
return HttpNotFound();
}
db.Entry(emprestimo).Reference(e => e.Livro).Load();
On a side note, you also don't need to create new context to get the Livros list, you have a perfectly good one already (db).
So instead of:
using (LibraryContext ctx = new LibraryContext())
{
Usuario u = (Usuario)Session["usuario"];
ViewBag.LivroId = new SelectList(db.Livro.Where(c => c.UsuarioId == u.UsuarioId), "LivroId", "Titulo");
return View(emprestimo);
}
Just do:
Usuario u = (Usuario)Session["usuario"];
ViewBag.LivroId = new SelectList(db.Livro.Where(c => c.UsuarioId == u.UsuarioId), "LivroId", "Titulo");
return View(emprestimo);
And, you actually don't need this new context anywhere, just use the "db" one.
I'm having trouble understanding how to retrieve and edit the DevId values from my CustomerDevice table in my database to the CheckBoxList based on the CustId value.
My Index Action Method for the CustomerDeviceController displays a list of Customers from my Customers table. I have an ActionLink labeled "Edit" that passes the CustId value to the CustomerDeviceController [HttpGet] Edit(int? id) Action Method which currently displays all CheckBoxListItem values from the Devices table. However, the CheckBoxList does not display the checked DevId values from the CustomerDevice table in the database to the CheckBoxList that pertain to the CustId, instead it displays a check for each of the CheckBoxList values.
The part that I'm having trouble understanding and figuring out, is how can I display the selected DevId values from the CustomerDevice table in my database to the CheckBoxList based on the CustId and then Edit/Update the modified CheckBoxListItems on the [HttpPost] Edit Action Method back to my CustomerDevice table in my database if need be.
Please see the following code below that I have so far.
Models
public class CheckBoxListItem
{
public int ID { get; set; }
public string Display { get; set; }
public bool IsChecked { get; set; }
}
public class Customer
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public string CustFirstName { get; set; }
....
}
public class Device
{
public int DevId { get; set; }
public string DevType { get; set; }
}
public class CustomerDevice
{
public int CustId { get; set; }
public int DevId { get; set; }
public Customer Customer { get; set; }
public Device Device { get; set; }
}
ViewModels
public class CustomerDeviceFormViewModel
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public List<CheckBoxListItem> Devices { get; set; }
}
CustomerDeviceController
public ActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerDeviceFormViewModel();
Customer customer = db.Customers.SingleOrDefault(c => c.CustId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustId = customer.CustId;
customervm.CustDisplayName = customer.CustDisplayName;
// Retrieves list of Devices for CheckBoxList
var deviceList = db.Devices.ToList();
var checkBoxListItems = new List<CheckBoxListItem>();
foreach (var device in deviceList)
{
checkBoxListItems.Add(new CheckBoxListItem()
{
ID = device.DevId,
Display = device.DevType,
IsChecked = deviceList.Where(x => x.DevId == device.DevId).Any()
});
}
customervm.Devices = checkBoxListItems;
return View(customervm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerDeviceFormViewModel vmEdit)
{
if (ModelState.IsValid)
{
Customer customer = db.Customers.SingleOrDefault(c => c.CustId == vmEdit.CustId);
if (customer == null)
{
return NotFound();
}
foreach (var deviceId in vmEdit.Devices.Where(x => x.IsChecked).Select(x => x.ID))
{
var customerDevices = new CustomerDevice
{
CustId = vmEdit.CustId,
DevId = deviceId
};
db.Entry(customerDevices).State = EntityState.Modified;
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vmEdit);
}
Edit.chtml
<div class="form-group">
Please select the Devices to assign to <b>#Html.DisplayFor(c => c.CustDisplayName)</b>
</div>
<div class="form-group">
#Html.EditorFor(x => x.Devices)
</div>
#Html.HiddenFor(c => c.CustId)
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
Shared/EditorTemplate/CheckBoxListItem.chtml
<div class="checkbox">
<label>
#Html.HiddenFor(x => x.ID)
#Html.CheckBoxFor(x => x.IsChecked)
#Html.LabelFor(x => x.IsChecked, Model.Display)
</label>
<br />
Your code for setting the IsChecked value will always return true (your loop is basically say if the collection contains me (which of course it does) then set it to true).
You need to get the selected values for each Customer by reading the values from your CustomerDevice table
Customer customer = db.Customers.SingleOrDefault(c => c.CustId == id);
if (customer == null)
{
return NotFound();
}
// Get all devices
var deviceList = db.Devices.ToList();
// Get the selected device ID's for the customer
IEnumerable<int> selectedDevices = db.CustomerDevices
.Where(x => x.CustId == id).Select(x => x.DevId);
// Build view model
var model = new CustomerDeviceFormViewModel()
{
CustId = customer.CustId,
CustDisplayName = customer.CustDisplayName,
Devices = deviceList.Select(x => new CheckBoxListItem()
{
ID = x.DevId,
Display = x.DevType,
IsChecked = selectedDevices.Contains(x.DevId)
}).ToList()
};
return View(model);
Here's a snippet of Razor code that I've used:
foreach (SelectListItem p in Model.PositionList)
{
#Html.Raw(p.Text + "<input type=checkbox name=\"PositionIDs\" id=\"PositionIDs\" value=" + #p.Value + (Model.Positions != null && Model.Positions.Any(pos => pos.ScoreCardId == Convert.ToInt32(p.Value)) ? " checked />" : " />"));
}
You might want to have a look at the MvcCheckBoxList NuGet package:
https://www.nuget.org/packages/MvcCheckBoxList/
This makes doing some powerful stuff with a CheckBoxList much easier in MVC - and may be a better approach to fixing your CheckBox issues.
I am trying to populate an HTML table with data from a table in my database. The issue is simply that the HTML table is not getting populated with any data.
Here is the ViewModel:
public class TestViewModel
{
public string MatchedId { get; set; }
public string UnmatchedId { get; set; }
public string Auth { get; set; }
public DateTime CreditDate { get; set; }
public string CreditNumber { get; set; }
public decimal CreditAmount { get; set; }
public DateTime DeniedDate { get; set; }
public int DeniedReasonId { get; set; }
public string DeniedNotes { get; set; }
}
Controller Action:
[HttpPost]
public ActionResult UploadValidationTable(HttpPostedFileBase csvFile)
{
var inputFileDescription = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true
};
var cc = new CsvContext();
var filePath = uploadFile(csvFile.InputStream);
var model = cc.Read<Credit>(filePath, inputFileDescription);
try
{
var entity = new Entities();
//model here is the .csv, doesn't have anything to do with this issue
foreach (var item in model)
{
var tc = new TemporaryCsvUpload
{
Id = item.Id,
CreditAmount = item.CreditAmount,
CreditDate = item.CreditDate,
CreditNumber = item.CreditNumber,
DeniedDate = item.DeniedDate,
DeniedReasonId = item.DeniedReasonId,
DeniedNotes = item.DeniedNotes
};
entity.TemporaryCsvUploads.Add(tc);
}
entity.SaveChanges();
System.IO.File.Delete(filePath);
//This is where the database table is getting filled
entity.Database.ExecuteSqlCommand("Insert into CsvReport Select p.Id as MatchedId, case when p.Id is null then t.Id end as UnmatchedId, p.Auth,p.CreditDate, p.CreditNumber,p.CreditAmount, p.DeniedDate,p.DeniedReasonId, p.DeniedNotes from TemporaryCsvUpload t left join PermanentTable p on p.Id = t.Id;");
TempData["Success"] = "Updated Successfully";
}
catch (LINQtoCSVException)
{
TempData["Error"] = "Upload Error: Ensure you have the correct header fields and that the file is of .csv format.";
}
return View("Upload");
}
View:
#model IEnumerable<TestProject.TestViewModel>
#if (Model != null)
{
foreach (var item in Model.Where(x => x.IdMatched != null))
{
<tr>
<td>
#item.MatchedId
</td>
<td>
#item.Auth
</td>
<td>
#item.CreditDate
</td>
<td>
#item.CreditNumber
</td>
<td>
#item.CreditAmount
</td>
<td>
#item.DeniedDate
</td>
<td>
#item.DeniedReasonId
</td>
<td>
#item.DeniedNotes
</td>
</tr>
}
}
It's a little weird because I am populating the database with an SQL command. What am I missing here? Do I need to try and pass it through the controller action? Let me know if you need more information. Thanks!
Edit
I tried to pass the instance through, but I may still be doing it incorrectly:
var testModel = new TestViewModel();
return View("Upload", testModel);
Here is what its padding through:
public class TestViewModel
{
public IEnumerable<Test> Test { get; set; }
}
Made an answer so essentially the view doesn't know what to render you need to pass an actual filled model (in your case an IEnumerable to the view). This can be done using the method:
View("Upload", viewModelList);
Controller.View docs on MSDN
It looks like you are not adding any data to your view model.
If your view model is a collection of Test objects, you need to add some
Test objects to the collection.
var model = new TestViewModel()
{
Test = new List<Test>() { new Test(), new Test(), ... }
}
return View("Upload", model);
I am having trouble with grouping a list, and then building a model that represents that list and displaying the results in a table within a view. For example:
List of items ordered
Date
CustomerId
Location
Item
Price
Quantity
How would I correctly model and display that list in a table if I wanted to group the list by location? And what if I wanted to group the list by two properties, for example, Location and CustomerId?
Here is my model:
public class ViewInvoice
{
public string ClientLocation { get; set; }
public List<DetailsGroup> Details { get; set; }
public class DetailsGroup
{
public List<string> Product { get; set; }
public List<string> ProductSize { get; set; }
public List<string> PackageType { get; set; }
public List<DateTime> OrderDate { get; set; }
public List<DateTime> DeliveryDate { get; set; }
public List<int> OrderNumber { get; set; }
public List<decimal> Price { get; set; }
public List<int> ItemQuantity { get; set; }
}
}
I am trying to display this model in a table within my razor view. Here is that code:
#using MyModel.MyTools.Orders.SumOrder
#model SumOrder
#{
ViewBag.Title = "View Invoice";
}
<h2>View Invoice</h2>
<table>
#foreach(var prod in Model.OCI)
{
<tr>
<td>
#prod.ClientLocation
</td>
</tr>
foreach (var orderItem in prod.Details)
{
<tr>
<td>
#orderItem.Product
</td>
<td>
#orderItem.ItemQuantity
</td>
</tr>
}
}
</table>
The first row in the table displays correctly, which is the name of a city, but in the next row I get this:
System.Collections.Generic.List1[System.String] System.Collections.Generic.List1[System.Int32]
Can someone explain to me why I can not get the list returned in a readable format, and how to correct this problem?
Here is the code I used to group the list for the ViewInvoice model:
public SumOrder(List<orders_Cart> order)
{
// create list of order cart item
List<OrderCartItems> cartItems = new List<OrderCartItems>();
// convert orders to ocm
foreach(var item in order)
{
var newCartItem = new OrderCartItems();
try
{
newCartItem.Product = db.product_Product.FirstOrDefault(p =>
p.Id == item.ProductId).ProductDescription ?? "none";
}
catch (Exception)
{
newCartItem.Product = "none";
}
try
{
newCartItem.ClientForProduct = MyTool.OrdersFindClientLocation(
(int) item.ClientForOrdersId);
}
catch (Exception)
{
newCartItem.ClientForProduct = new object[3];
}
try
{
newCartItem.ProductSize = db.products_Size.FirstOrDefault(p => p.Id ==
item.ProductSizeId).ProductSizeCode ?? "none";
}
catch (Exception)
{
newCartItem.ProductSize = "none";
}
try
{
newCartItem.PackageType = db.packaging_PackageType.FirstOrDefault(p =>
p.Id == item.PackageTypeId).PackageTypeCode ?? "none";
}
catch (Exception)
{
newCartItem.PackageType = "none";
}
newCartItem.OrderDate = (DateTime) item.OrderDate;
newCartItem.DeliveryDate = (DateTime) item.DeliveryDate;
newCartItem.OrderNumber = (int) item.OrderNumber;
newCartItem.Price = (decimal) item.Price;
newCartItem.ClientLocation = MyTool.OrdersFindClientLocation(
(int) item.ClientForOrdersId, null);
newCartItem.ItemQuantity = (int) item.Quantity;
cartItems.Add(newCartItem);
}
// group the cartItems according to location
List<ViewInvoice> ordersGrouped = cartItems.GroupBy(c => new
{c.ClientLocation})
.OrderBy(c => c.Key.ClientLocation).Select(s =>
new ViewInvoice()
{
ClientLocation = s.Key.ClientLocation,
Details = new List<ViewInvoice.DetailsGroup>()
{
new ViewInvoice.DetailsGroup()
{
Product = s.Select(p => p.Product).ToList(),
ItemQuantity = s.Select(p => p.ItemQuantity).ToList(),
DeliveryDate = s.Select(p => p.DeliveryDate).ToList(),
OrderDate = s.Select(p => p.OrderDate).ToList(),
OrderNumber = s.Select(p => p.OrderNumber).ToList(),
PackageType = s.Select(p => p.PackageType).ToList(),
Price = s.Select(p => p.Price).ToList(),
ProductSize = s.Select(p => p.ProductSize).ToList()
}
}
}).ToList();
// set the OCI property
OCI = ordersGrouped;
};
Ok, I finally solved my problem. I initially over-thought the problem. I simplified my model, and added some simple logic to my view.
Here is the updated Model:
public class ViewInvoice
{
public string ClientLocation { get; set; }
public List<string> Product { get; set; }
public List<string> ProductSize { get; set; }
public List<string> PackageType { get; set; }
public List<DateTime> OrderDate { get; set; }
public List<DateTime> DeliveryDate { get; set; }
public List<int> OrderNumber { get; set; }
public List<decimal> Price { get; set; }
public List<int> ItemQuantity { get; set; }
}
the updated code used to group the list for the Model:
// group the cartItems according to location
List<ViewInvoice> ordersGrouped = cartItems.GroupBy(c => new
{c.ClientLocation})
.OrderBy(c => c.Key.ClientLocation).Select(s =>
new ViewInvoice()
{
ClientLocation = s.Key.ClientLocation,
Product = s.Select(p => p.Product).ToList(),
ItemQuantity = s.Select(p => p.ItemQuantity).ToList(),
DeliveryDate = s.Select(p => p.DeliveryDate).ToList(),
OrderDate = s.Select(p => p.OrderDate).ToList(),
OrderNumber = s.Select(p => p.OrderNumber).ToList(),
PackageType = s.Select(p => p.PackageType).ToList(),
Price = s.Select(p => p.Price).ToList(),
ProductSize = s.Select(p => p.ProductSize).ToList()
}).ToList();
and the updated view:
#using MyModel.MyTools.Orders.SumOrder
#model SumOrder
#{
ViewBag.Title = "View Invoice";
}
<h2>View Invoice</h2>
#{
int i = 0;
}
<table>
#foreach(var mod in Model.OCI)
{
var modCount = #mod.Product.Count();
<tr>
<th>#mod.ClientLocation</th>
</tr>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
foreach (var items in mod.Product)
{
<tr>
<td>
#mod.Product.ElementAtOrDefault(i)
</td>
<td>
#mod.Price.ElementAtOrDefault(i)
</td>
</tr>
i++;
}
}
</table>
This solution clearly allows me to iterate through the model reproducing any required rows or cells along the way. Played Russian roulette for two days over this problem. Hope this saves some others some time.