Trouble passing data from database table to view - c#

I am filling an SQL table with a query and then trying to pass the data from the model (for the table) into the view. I am attempting to use a ViewModel to pass the data to the view in a Controller Action.
Here is the Model:
public partial class Report
{
public int Id { get; set; }
public string Number { get; set; }
public Nullable<decimal> Amount { get; set; }
public Nullable<System.DateTime> Date { get; set; }
public Nullable<int> ReasonId { get; set; }
public string Notes { get; set; }
}
IEnumerable ViewModel:
public class ReportViewModel
{
public IEnumerable<Report> Reports { get; set; }
}
Controller Action:
[HttpPost]
public ActionResult UploadValidationTable(HttpPostedFileBase csvFile)
{
//Unrelated Code to read a CSV into another database table goes here
//But was removed so it wouldn't be confusing.
var db = new Report();
var reportModel = new ReportViewModel()
{
Reports = new List<Report>() {new Report()}
};
return View("Upload", reportModel);
}
View:
#model Entities.Models.ReportViewModel
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Number</th>
<th>Amount</th>
<th>Date</th>
<th>Reason Id</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
foreach (var item in Model.Reports.Where(x => x.Id != null))
{
<tr>
<td>
#item.Id
</td>
<td>
#item.Number
</td>
<td>
#item.Amount
</td>
<td>
#item.Date
</td>
<td>
#item.ReasonId
</td>
<td>
#item.Notes
</td>
</tr>
}
}
</tbody>
</table>
But I get an exception when I try to return the View which says ReportViewModel is not assignable to model type IEnumerable ReportViewModel
So I am just trying to pass all the rows from the Report database to an HTML table in my view. Any help, or a better way to do this would be appreciated.

Related

foreach statement cannot operate because does not contain a public definition for 'GetEnumerator' with Tuples ASP.NET MVC

I want to build my view and join 2 tables using LINQ but i got this error in view in foreach in Model
#foreach (var item in Model)
This is my classes :
public partial class Lab_orders_Cash
{
[Display(Name = "Order Id")]
public int cash_order_id { get; set; }
[Display(Name = "Order Date")]
public Nullable<System.DateTime> order_date { get; set; }
[Display(Name = "MRN File No.")]
public Nullable<int> patient_no { get; set; }
public string invoice_order_no { get; set; }
public string order_description { get; set; }
public string user_id { get; set; }
[Display(Name = "Order Status")]
public Nullable<int> order_status { get; set; }
public Nullable<int> catid { get; set; }
public Nullable<int> almansoor { get; set; }
public Nullable<int> prio_id { get; set; }
}
public partial class Lab_Sample_status
{
public int status_id { get; set; }
public string status_name { get; set; }
}
this my controller :
public ActionResult ordersCash()
{
var OrdersList = from o in db.Lab_orders_Cash
Join os in db.Lab_Sample_status on o.order_status equals os.status_id into tablestatus
where o.patient_no == (int)Session["UserpatientNo"]
select o;
return View(OrdersList);
}
In view i used Tuples :
#using AljawdahNewSite.Models;
#model Tuple<Lab_orders_Cash,Lab_Sample_status>
#{
#{
ViewBag.Title = "ordersCash";
Layout = "~/Views/Shared/_LayoutPatients.cshtml";
}
<h2>Orders List </h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(Tuple => Tuple.Item1.cash_order_id)
</th>
<th>
#Html.DisplayNameFor(Tuple => Tuple.Item1.order_date)
</th>
<th>
#Html.DisplayNameFor(Tuple => Tuple.Item1.patient_no)
</th>
<th>
#Html.DisplayNameFor(Tuple => Tuple.Item2.status_name)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(Tuple => Tuple.Item1.cash_order_id)
</td>
<td>
#Html.DisplayFor(Tuple => Tuple.Item1.order_date)
</td>
<td>
#Html.DisplayFor(Tuple => Tuple.Item1.patient_no)
</td>
<td>
#Html.DisplayFor(Tuple => Tuple.Item2.status_name)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.cash_order_id })
</td>
</tr>
}
</table>
in foreach when select model i got this error , also i tried to use IEnumerable in view like this
#model Tuple<IEnumerable<Lab_orders_Cash>,IEnumerable<Lab_Sample_status>>
but same error when i select Model it shows the error
What i need to change to solve this error.
you can use another way like the following steps :
1- Create new class and put your tables in that class
public class Tables
{
public Lab_orders_Cash LabOrdersCash { get; set; }
public Lab_Sample_status LabOrderStatus { get; set; }
}
2- Write the controller like the following :
public ActionResult ordersCash()
{
List<Lab_orders_Cash> ordercash = db.Lab_orders_Cash.ToList();
List<Lab_Sample_status> samplestatus = db.Lab_Sample_status.ToList();
var OrdersList = from o in ordercash
join st in samplestatus on o.order_status equals st.status_id
where o.patient_no == (int)Session["UserpatientNo"]
select new Tables{ LabOrdersCash = o , LabOrderStatus = st };
return View(OrdersList);
}
3- Create your view use the following code :
#model IEnumerable<AljawdahNewSite.Models.Tables>
#{
ViewBag.Title = "ordersCash";
Layout = "~/Views/Shared/_LayoutPatients.cshtml";
}
<h2>Orders List</h2>
<table class="table">
<tr>
<td> Order No. </td>
<td> order date </td>
<td> Patient No </td>
<td> Status </td>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.LabOrdersCash.cash_order_id</td>
<td>#item.LabOrdersCash.order_date</td>
<td>#item.LabOrdersCash.patient_no</td>
<td>#item.LabOrderStatus.status_name</td>
</tr>
}
</table>
This way more effective and easily you can add all your tables in this tables class and call this class any where in your project and easier than Tuples.

Serveral models in one view ASP.net core with EF core

I want to create a Dashboard of two tables and a chart of data in the database using ASP.net Core 3.1 and EF Core 3.
This the teacher model class:
public class Teacher
{
[Key]
public Int64 ID { get; set; }
public Sring Name { get; set; }
public int Age { get; set; }
}
this is the course model class :
public class Course
{
[Key]
public Int64 ID { get; set; }
public Sring Name { get; set; }
public Sring TargetClass { get; set; }
}
The ViewModel class is as follows:
public class DashboardViewModel
{
public List<Course> Course { get; set; }
public List<Teacher> Teacher { get; set; }
}
the index page is :
<h2> Table of Teacher</h2>
<table>
<thead>
<tr>
<th> ID</th>
<th> Name</th>
<th> Age</th>
</tr>
</thead>
<tbody>
#foreach (Teacher item in Model.Teacher)
{
<tr>
<td>
#item.ID
</td>
<td>
#item.Name
</td>
<td>
#item.Age
</td>
</tr>
}
</tbody>
</table>
<h2> Table of Courses</h2>
<table>
<thead>
<tr>
<th> ID</th>
<th> Name</th>
<th> TargetClass</th>
</tr>
</thead>
<tbody>
#foreach (Teacher item in Model.Course)
{
<tr>
<td>
#item.ID
</td>
<td>
#item.Name
</td>
<td>
#item.TargetClass
</td>
</tr>
}
</tbody>
</table>
The home controller is :
public class HomeController : Controller
{
private readonly ApplicationDbContext _context;
public HomeController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
var qry = await _context.Teacher.ToListAsync();
var Teachers = new List<Teacher>(){};
var Courses = new List<Courses>() { };
var Dash = new DashboardViewModel {
Course = Courses,
Teacher = Teachers
};
return View(Dash);
}
The Problem appears when trying to pass the data from qry variable to list.
Question : How I can pass the data from EF to List of Teachers as the example?
var qry = _context.Teacher.ToListAsync();
var Teachers = new List<Teacher>(){qry};
Without convert error :
cannot convert from 'System.Threading.Tasks.Task<System.Collections.Generic.List<School.Models.Teacher>>' to 'School.Models.Teacher'
I can't do this in comments, so I will put this here and then I can amend the answer if it's not quite right. You don't need to create empty lists beforehand, just create the ViewModel all in one shot. As I think jegtugado was trying to suggest, the Index() code should look something like:
public async Task<IActionResult> Index()
{
var Dash = new DashboardViewModel {
Course = await _context.Course.ToListAsync(),
Teacher = await _context.Teacher.ToListAsync()
};
return View(Dash);
}
This is assuming your DbSets are called Teacher and Course (but these are often plural, so double check that).

C# , MVC , Instead table html

I have this model :
public class CoursesTeacher
{
public int Id { get; set; }
public string FullName { get; set; }
public IEnumerable<string> CourseName { get; set; }
public IEnumerable<int> CourseId { get; set; }
}
I would like to create an Instead table html by razor.
The teacher has a multiple courses.
like that
that
I wrote this code :
<table class="table table-bordered">
<tr>
<th>
#Html.ActionLink("Teacher Name", "RequestsTeachers")
</th>
<th>
#Html.ActionLink("Corese Name", "RequestsTeachers")
</th>
<th>
Edit
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td rowspan="#item.CourseName.Count()">
#Html.DisplayFor(modelItem => item.FullName)
</td>
#foreach (var courseName in item.CourseName)
{
<td>
#Html.DisplayFor(modelItem => courseName)
</td>
}
#foreach (var courseId in item.CourseId)
{
<td>
<div class="pull-right">
#Html.NoEncodeActionLink("<span class='glyphicon glyphicon-pencil'></span>", "Edit", "EditFinancial", "Control", routeValues: new { courseId = courseId }, htmlAttributes: new { data_modal = "", #class = "btn btn-default" })
</div>
</td>
}
</tr>
}
but created not correct :
correct
how to create correct ?
I'd go and create a viewmodel to represent the info for a course:
public class CourseInfoModel
{
public string CourseName { get; set; }
public int CourseId { get; set; }
public bool IsFirstCourse { get; set; }
}
Then in the model class, create a readonly property to get the data in a more suitable way:
public class CoursesTeacher
{
public int Id { get; set; }
public string FullName { get; set; }
public IEnumerable<string> CourseName { get; set; }
public IEnumerable<int> CourseId { get; set; }
public IList<CourseInfoModel> Courses
{
get
{
if (CourseName == null || CourseId == null || CourseId.Count() != CourseName.Count())
throw new Exception("Invalid data"); //courses and ids must have the same number of elements
var list = new List<CourseInfoModel>();
for (int i = 0; i < CourseName.Count(); i++)
{
list.Add(new CourseInfoModel
{
IsFirstCourse = i == 0,
CourseId = CourseId.ElementAt(i),
CourseName = CourseName.ElementAt(i),
});
}
return list;
}
}
}
Now in the view is easy to render the table the way you want:
#model IEnumerable<MvcTable.Models.CoursesTeacher>
<table class="table table-bordered">
<tr>
<th>
#Html.ActionLink("Teacher Name", "RequestsTeachers")
</th>
<th>
#Html.ActionLink("Course Name", "RequestsTeachers")
</th>
<th>
Edit
</th>
</tr>
#foreach (var item in Model)
{
foreach (var courseItem in item.Courses)
{
<tr>
#if (courseItem.IsFirstCourse)
{
<td rowspan="#item.Courses.Count">
#Html.DisplayFor(modelItem => item.FullName)
</td>
}
<td>
#Html.DisplayFor(modelItem => courseItem.CourseName)
</td>
<td>
<div class="pull-right">
<span class='glyphicon glyphicon-pencil'></span>
</div>
</td>
</tr>
}
}
</table>
Instead of keeping the CourseName and CourseIds to seperate lists. Why not create a class to represent a course and use that ?
public class CourseVm
{
public int Id { set; get;}
public string Name { set; get;}
}
public class CoursesTeacher
{
public int Id { set;get;}
public string FullName { set;get;}
public List<CourseVm> Courses { set;get;}
}
and in the view which is strongly typed to a collection CoursesTeacher
#model IEnumerable<CoursesTeacher>`
<table>
#foreach(var t in Model)
{
<tr>
<td>#t.FullName</td>
<td>
<table>
#foreach(var c in t.Courses)
{
<tr><td>#c.Name</td>
<td><button>Some button</button></td>
</tr>
}
</table>
</td>
</tr>
}
</table>

Trying to get the Selected checkbox values with the ID value

Below is the Model
public class M_ProjectType
{
public Int16 ProjectTypeID { get; set; }
public String ProjectType { get; set; }
public Boolean IsActive { get; set; }
public Decimal Cost { get; set; }
public String Description { get; set; }
public Boolean IsChecked { get; set; }
}
Below is View Model
public class VM_Project
{
public string[] SkillID { get; set; }
public List<M_ProjectType> ProjectType { get; set; }
}
Below is Get Action method. here I am getting the data for projects that will be sent to View Model
[HttpGet, Route("Project")]
public async Task<ActionResult> Project()
{
var projectTypes = (await _projectTypes.ProjectTypesList()).Value;
var list = new List<M_ProjectType>();
foreach (var item in projectTypes)
{
list.Add(new M_ProjectType
{
Cost = item.Cost,
Description = item.Description,
IsActive = item.IsActive,
IsChecked = false,
ProjectType = item.ProjectType,
ProjectTypeID = item.ProjectTypeID
}
);
}
var project = new VM_Project
{
ProjectType = list
};
return View(project);
}
Below is Razor View
#foreach (var item in Model.ProjectType)
{
<table class="table table-striped">
<tbody>
<input type="hidden" value="#item.ProjectTypeID" name="ProjectTypeID" />
<tr>
<td style="width:5%">
#Html.CheckBoxFor(i => item.IsChecked, new { #class = "tableflat" })
#Html.HiddenFor(i => item.ProjectTypeID)
</td>
<td style="width:10%">#item.ProjectType</td>
<td style="width:80%">#item.Description</td>
<td style="width:5%"><b>$#item.Cost</b></td>
</tr>
</tbody>
</table>
}
Below is Post Action Method
[HttpPost, Route("Project")]
public ActionResult Project(VM_Project project)
{
return View();
}
Question: I am getting project.ProjectType = null. Any suggestion why
this is happening ?
I would recommend using EditorTemplates.
Create a folder named EditorTemplates in you Views/Shared direcotry.
Create a partial view based on your type i.e. M_ProjectType.cshtml
Put your markup that you use in foreach loop in M_ProjectType.cshtml file
#model M_ProjectType
<table class="table table-striped">
<tbody>
<tr>
<td style="width:5%">
#Html.CheckBoxFor(i => i.IsChecked, new { #class = "tableflat" })
#Html.HiddenFor(i => i.ProjectTypeID)
</td>
<td style="width:10%">#Model.ProjectType
#Html.HiddenFor(i=>i.ProjectType)
</td>
<td style="width:80%">#Model.Description</td>
<td style="width:5%"><b>$#Model.Cost</b></td>
</tr>
</tbody>
Then render your editor template in your form like (note: no foreach loop)
#Html.EditorFor(m=>m.ProjectType)
You should get correct model binded to your html elements back in controller.
Try this:
#foreach (var item in Model.ProjectType)
{
<table class="table table-striped">
<tbody>
<tr>
<td style="width:5%">
#Html.CheckBoxFor(i => item.IsChecked, new { #class = "tableflat" })
#Html.HiddenFor(i => item.ProjectTypeID, new { #Value = item.ProjectTypeID})
</td>
</tr>
</tbody>
</table>
}

Print Table with List Variable From Entities in MVC

I've not worked MVC for a long time; I'm a fresh guy to this. So, I have these two entities:
// Entity Worker
[Display(Name = "ID")]
public Int32 Id { get; set; }
[Display(Name = "Número")]
public Int32 Numero { get; set; }
[Display(Name = "Nome")]
// Entity Lottery
public Int32 Id { get; set; }
[Display(Name = "Tipo")]
public String Tipo { get; set; }
[Display(Name = "Data")]
public DateTime Data { get; set; }
[Display(Name = "Observações")]
public List<Worker> FuncionariosSorteados { get; set; }
So, for each lottery entity, I will have a List of workers. I am passing the values to the View by the controller, like this:
public ActionResult Details(int id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Lottery lottery = service.FindLottery(id);
if (sorteio == null)
{
return HttpNotFound();
}
return View(lottery);
}
Where the service is my Repository for the connection to database (in this case he do a search by ID on database to get the right lottery.
Here my doubt begin, if I want to do a table for the lotteries, I can do it doing (using Lottery model)
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Tipo)
</td>
<td>
#Html.DisplayFor(modelItem => item.Data)
</td>
<td>
#Html.DisplayFor(modelItem => item.Observacoes)
</tr>
}
But how I can do the same for the public List<Worker> FuncionariosSorteados? I just want to print the public List<Worker> FuncionariosSorteados in a GridMvc table, but through the model I cant have access to it!
I believe you need to iterate through the list within the foreach loop you already created. Something like this:
#foreach (var item in Model)
{
<table>
<tr>
<td>
#Html.DisplayFor(modelItem => item.Tipo)
</td>
<td>
#Html.DisplayFor(modelItem => item.Data)
</td>
<td>
#Html.DisplayFor(modelItem => item.Observacoes)
</td>
</tr>
</table>
<table>
#foreach(var w in Model.FuncionariosSorteados )
{
<tr>
<td>#Html.DisplayFor(w => w.Id)</td>
<td>#Html.DisplayFor(w => w.Numero)</td>
</tr>
}
</table>
}
I'm confused because in your action, you're pulling a single lottery record and passing that to your view, but in your view, you're iterating through what appears to be an IEnumerable<Lottery>.
Since you'd have no issues accessing FuncionariosSorteados off of a Model of type Lottery, I'm assuming the view is actually using IEnumerable<Lottery>. For an enumerable, you have to iterate over the list and access the properties on the individual items. For example:
#model IEnumerable<Lottery>
#Model.FuncionariosSorteados <!-- fail -->
#foreach (var lottery in Model)
{
#lottery.FuncionariosSorteados <!-- success -->
}
For your second entity you could create it like this:
Entitie Lottery
public Lottery( )
{
FuncionariosSorteados = new List <Worker>();
}
public Int32 Id { get; set; }
[Display(Name = "Tipo")]
public String Tipo { get; set; }
[Display(Name = "Data")]
public DateTime Data { get; set; }
[Display(Name = "Observações")]
public virtual List<Worker> FuncionariosSorteados { get; set; }
And thenin your view you can use a foreach loup to iterate inside the lists

Categories

Resources