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>
Related
I have 2 models; TypeOne and Project_Screen. I need a view that makes 2 tables with information from both of those tables. I tried to use this guide to making a view model which helped but isnt doing quite the same thing I am: https://dotnettutorials.net/lesson/view-model-asp-net-core-mvc/
This is the View Model I made:
public class MyProjectsViewModel
{
public Project_Screen Project_Screen { get; set; }
public TypeOne TypeOne { get; set; }
}
This is the controller:
public class ProfileController : Controller
{
private readonly Natural_ResourcesContext _context;
public ProfileController(Natural_ResourcesContext context)
{
_context = context;
}
// GET: Profile
public ActionResult Index()
{
Project_Screen project_Screen = (Project_Screen)(from s in _context.Project_Screen
where s.DSN_PM == User.Identity.Name
select s);
TypeOne typeOne = (TypeOne)(from x in _context.TypeOne
where x.Name == User.Identity.Name
select x);
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
return View(myProjectsViewModel);
}
}
As you can see, project_Screen and typeOne are all records in which Manager = Name.
Then in the view I'd like to display these something like this:
#model EnvApp.ViewModels.MyProjectsViewModel
#{
ViewData["Title"] = "Projects";
}
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.County)
</td>
<td>
#Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="#item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.County)
</td>
<td>
#Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="#item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
I get the compiler error CS1579 on ````Model```:
foreach statement cannot operate on variables of type 'MyProjectsViewModel' because 'MyProjectsViewModel' does not contain a public instance or extension definition for 'GetEnumorator'
Which I think makes sense, because I have not denoted Project_Screen or TypeOne as an object that holds multiple records, but I'm not quite sure how to do this.
Am I on the right track or have I misunderstood this? What am I missing?
EDIT 1:
I did exactly what Md Farid Uddin Kiron said so the code in his answer reflects my view model and view. However I am still having issues with my controller.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using EnvApp.ViewModels;
using EnvApp.Models.DB;
namespace EnvApp.Controllers
{
public class ProfileController : Controller
{
private readonly Natural_ResourcesContext _context;
public ProfileController(Natural_ResourcesContext context)
{
_context = context;
}
// GET: Profile
public ActionResult Index()
{
Project_Screen project_Screen = (Project_Screen)(from s in _context.Project_Screen
where s.DSN_PM == User.Identity.Name
select s);
TypeOne typeOne = (TypeOne)(from x in _context.TypeOne
where x.Name == User.Identity.Name
select x);
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
return View(myProjectsViewModel);
}
}
}
The issue is that project_Screen and typeOne aren't lists or IEnumerable types, which makes sense, but I'm not the syntax to get them to be enumerable.
IF you need to see it, here is my view model:
public class MyProjectsViewModel
{
public List<Project_Screen> Project_Screen { get; set; }
public List<TypeOne> TypeOne { get; set; }
}
And here is the View:
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Project_Screen)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.County)
</td>
<td>
#Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="#item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TypeOne)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.County)
</td>
<td>
#Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="#item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
Again, the issue is that project_Screen and typeOne aren't lists or IEnumerable types IN THE CONTROLLER. They are Lists in actuallity and everywhere EXCEPT the controller but they need to be. The error is on the lines
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
on project_Screen and typeOne and reads
cannot implicitly convert type Envapp.Models.DB.Project_Screen to System.Collection.Generic.List<Envapp.Models.DB.Project_Screen>
This appears to be happening because the code there is trying to point to the DB model table for Project_Screen rather than the ViewModel representation of items in the Project_Screen model. How do I fix this?
EDIT 2:
I'm not sure what it is but something in my code seems to be really confusing people. I am posting all of my models for clarification:
Project_Screen.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
#nullable disable
namespace EnvApp.Models.DB
{
public partial class Project_Screen
{
[Key]
public long ID { get; set; }
public string State_Project_Number { get; set; }
public string? Federal_Project_Number { get; set; }
public string Project_Name { get; set; }
public string County { get; set; }
public DateTime? Memo_Date { get; set; }
public string From { get; set; }
public string? Authorization { get; set; }
public string DSN_PM { get; set; }
public string? History { get; set; }
public string History_PM { get; set; }
public bool Review_Exempt_H { get; set; }
public bool SHPO_Approval_H { get; set; }
public string? Archaeology { get; set; }
public string Archaeology_PM { get; set; }
public bool Review_Exempt_A { get; set; }
public bool SHPO_Approval_A { get; set; }
public bool ESA_Key { get; set; }
public bool Crayfish { get; set; }
public bool Crayfish_Habitat_Assessment { get; set; }
public bool NLEB_4D { get; set; }
public bool USFWS { get; set; }
public string USFWS_Type { get; set; }
public bool Mussel_Habitat { get; set; }
public bool Mussel_Stream { get; set; }
public string Within_Airport { get; set; }
public string? ToPo_Quad_Name { get; set; }
public bool Bat_Habitat { get; set; }
public string? Bars { get; set; }
public string Coordinates { get; set; }
public string? Natural_Resources_Notes { get; set; }
public string Adduser { get; set; }
public DateTime? Date_Added { get; set; }
public string Crayfish_Notes { get; set; }
public string Mussel_Notes { get; set; }
}
}
TypeOne.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace EnvApp.Models.DB
{
[Table("Type_One")]
public partial class TypeOne
{
[Key]
public long ID { get; set; }
[MaxLength(50)]
public string State_Project_Number { get; set; }
[MaxLength(50)]
public string Federal_Project_Number { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(50)]
public string Route_Number { get; set; }
public string County { get; set; }
[MaxLength(50)]
public string Work_Type { get; set; }
[MaxLength(100)]
public string Coordinates { get; set; }
public string Project_Description { get; set; }
public bool? Federal_Aid { get; set; }
public bool? Minimal_Project_Verification { get; set; }
[MaxLength(3)]
public string CE_Category { get; set; }
[MaxLength(10)]
public string Amms { get; set; }
public bool Activities_Agreement { get; set; }
public string Arch_RE { get; set; }
public string Hist_RE { get; set; }
public DateTime? Arch_RE_Date { get; set; }
public DateTime? Hist_RE_Date { get; set; }
public bool? Through_Lanes { get; set; }
public bool? Close_Road { get; set; }
public bool? ROW_Acquisition { get; set; }
public bool? Access_Control { get; set; }
public bool? Fifty_Year_Structure { get; set; }
public bool? Agency_Coordination { get; set; }
public bool? IPAC_Screening_Zone { get; set; }
public bool? Section_404_Permit { get; set; }
public bool? Ground_Disturbance { get; set; }
public bool? Waterway { get; set; }
public bool? Special_Use_Permit { get; set; }
public bool? Floodplain { get; set; }
public string Prepared_By { get; set; }
public string Approved_By { get; set; }
public string Adduser { get; set; }
public DateTime? Date_Added { get; set; }
}
}
Natural_ResourcesContext
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
#nullable disable
namespace EnvApp.Models.DB
{
public partial class Natural_ResourcesContext : DbContext
{
public Natural_ResourcesContext()
{
}
public Natural_ResourcesContext(DbContextOptions<Natural_ResourcesContext> options)
: base(options)
{
}
public virtual DbSet<NR_User> NR_Users { get; set; }
public virtual DbSet<Project_Screen> Project_Screen { get; set; }
public virtual DbSet<TypeOne> TypeOne { get; set; }
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
The error is because you are using foreach on the view model itself, not on the properties you want to enumerate.
For Project_Screen and TypeOne, declare them as an enumerable type (eg. Array, List, IEnumerable, etc).
public class MyProjectsViewModel
{
public IEnumerable<Project_Screen> Project_Screen { get; set; }
public IEnumerable<TypeOne> TypeOne { get; set; }
}
You will need to populate those with a collection of values from the controller
var viewModel = new MyProjectsViewModel();
viewModel.Project_Screen = _context.Project_Screen.Where(x => SOME_CONDITION);
viewModel.TypeOne = _context.TypeOne.Where(x => SOME_CONDITION);
In the view you will enumerate those properties (not the model itself).
#foreach (var item in Model.Project_Screen)
and
#foreach (var item in Model.TypeOne)
You were close enough. It seems your Project_Screen and Type_One should be list kind of class from your view iteration we got to know. If so, then your MyProjectsViewModel should be like:
View Model:
public class MyProjectsViewModel
{
public List<Project_Screen> ProjectScreen { get; set; }
public List<Type_One> TypeOne { get; set; }
}
Controller:
public ActionResult ViewModelEnumeration()
{
var proScreen = new List<Project_Screen>()
{
new Project_Screen(){ State_Project_Number = 1,Federal_Project_Number =1,Project_Name = "Project-1", County = "USA"},
new Project_Screen(){ State_Project_Number = 2,Federal_Project_Number =2,Project_Name = "Project-2", County = "CA"},
new Project_Screen(){ State_Project_Number = 3,Federal_Project_Number =3,Project_Name = "Project-3", County = "UK"},
};
var typeOne = new List<Type_One>()
{
new Type_One(){ State_Project_Number = 101,Federal_Project_Number =101,Project_Name = "Type-One-Project-1", County = "USA"},
new Type_One(){ State_Project_Number = 102,Federal_Project_Number =102,Project_Name = "Type-One-Project-2", County = "CA"},
new Type_One(){ State_Project_Number = 103,Federal_Project_Number =103,Project_Name = "Type-One-Project-3", County = "UK"},
};
//Bind to View Model
MyProjectsViewModel viewModel = new MyProjectsViewModel();
viewModel.ProjectScreen = proScreen;
viewModel.TypeOne = typeOne;
return View(viewModel);
}
Note: I am binding demo seeder property into the list. Feel free to change as per your requirement.Just getting you into the point.
View:
#model MVCApps.Models.MyProjectsViewModel
#{
ViewData["Title"] = "ViewModelEnumeration";
}
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.ProjectScreen)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.County)
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TypeOne)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.County)
</td>
</tr>
}
</tbody>
</table>
Output:
Note: So according to your scenario you can use like this #foreach (var item in Model.Project_Screen). Additionally, be
conscious about your naming convention like Project_Screen Project_Screen is confusing either practice like Project_Screen ProjectScreen or ProjectScreen Project_Screen.
Hope above steps guide you accordingly. You can enhance your Idea more about this on our official document here
Update:
As per your comment I am also adding the example in case of single
object means when you have other than List or IEnumerable
View Model:
public class ProjectsScreenTypeOneViewModel
{
public Project_Screen ProjectScreen { get; set; }
public Type_One TypeOne { get; set; }
}
Controller:
public ActionResult ViewModelFromSingleObject()
{
//Binding Project_Screen Object
var _proScreen = new Project_Screen();
_proScreen.Project_Name = "Test Project-202";
_proScreen.State_Project_Number = 1111;
_proScreen.Federal_Project_Number = 11112021;
_proScreen.County = "USA";
//Binding Type_One Object
var _typeOne = new Type_One();
_typeOne.Project_Name = "Test Type One Project-101";
_typeOne.State_Project_Number = 1010;
_typeOne.Federal_Project_Number = 202121;
_typeOne.County = "UK";
//Binding to view model
var _viewModel = new ProjectsScreenTypeOneViewModel();
_viewModel.ProjectScreen = _proScreen;
_viewModel.TypeOne = _typeOne;
return View(_viewModel);
}
View:
#model MVCApps.Models.ProjectsScreenTypeOneViewModel
#{
ViewData["Title"] = "ViewModelFromSingleObject";
}
<h2>ViewModelFromSingleObject</h2>
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
#Html.DisplayFor(modelItem => Model.ProjectScreen.State_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ProjectScreen.Federal_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ProjectScreen.Project_Name)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ProjectScreen.County)
</td>
</tr>
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
#Html.DisplayFor(modelItem => Model.TypeOne.State_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => Model.TypeOne.Federal_Project_Number)
</td>
<td>
#Html.DisplayFor(modelItem => Model.TypeOne.Project_Name)
</td>
<td>
#Html.DisplayFor(modelItem => Model.TypeOne.County)
</td>
</tr>
</tbody>
</table>
Output:
Note: Now as you can see I have added both single and List kind of example which will guided you accordingly. If you still
encounter any further issue feel free to share.
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.
I am going to create a delete button for my table
here is my code
<center>
<H2>LIST OF REGISTERED STUDENTS</H2>
<br /><br />
</center>
<table class="table">
<tr>
<th>
Name
</th>
<th>
Last Name
</th>
<th>
E-Mail
</th>
<th>
Password
</th>
<th>
Student Number
</th>
<th>
Program
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.student_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_lname)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_email)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_password)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_number)
</td>
<td>
#Html.DisplayFor(modelItem => item.student_program)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.student_name }) |
#Html.ActionLink("Details", "Details", new { id=item.student_name }) |
#Html.ActionLink("Delete", "Delete", new { id=item.student_name })
</td>
</tr>
}
</table>
but when I create the delete syntax
public ActionResult Delete(int id = 0)
{
CSdbConnectionString db = new CSdbConnectionString();
student student = db.students.Find(id);
if(student == null)
{
return HttpNotFound();
}
return View(student);
}
// POST: Student/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
CSdbConnectionString db = new CSdbConnectionString();
try
{
student student = db.students.Find(id);
db.students.Remove(student);
db.SaveChanges();
return RedirectToAction("ViewStudents","ConsulSked");
}
catch
{
return View();
}
}
the code db.students.Find(id) has an error of
Cannot implicitly convert type CS.Models.student to CS.student
here is my student class
[Table("student")]
public class student
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int student_id { get; set; }
public string student_name { get; set; }
public string student_lname { get; set; }
public string student_email { get; set; }
public string student_password { get; set; }
public string student_number { get; set; }
public string student_program { get; set; }
}
and this is my data context class
public class CSdbConnectionString : DbContext
{
public CSdbConnectionString()
: base("CSdbConnectionString")
{ }
public DbSet<appointment> appointments { get; set; }
public DbSet<faculty> faculties { get; set; }
public DbSet<sched> scheds { get; set; }
public DbSet<student> students { get; set; }
}
what should I do? I can't create the delete option.
I have found the solution, for those in the future who will have the same error.
It is because I have a .dbml file in my project so I can store my stored procedures. That is the
CS.student
the one in my namespace model is the
CS.Models.student
and that's the one we need.
So instead of
student student = db.students.Find(id);
make it
CS.Models.student student = db.students.Find(id);
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>
}
view
#model List<PMS.View_Model._ContributeViewModel>
#{
ViewBag.Title = "Contribute";
}
#using (Html.BeginForm())
{
#Html.Partial("_Project")
#Html.ValidationSummary(true)
<table>
<tr>
<th>
<u>Current Members</u>
</th>
</tr>
<tr>
<th>
ProjectID
</th>
<th>
Name
</th>
<th>
Role
</th>
</tr>
#foreach(var item in Model.Where(m=>m.Status==1))
{
<tr>
<td>
#Html.DisplayFor(model=>item.ProjectID)
</td>
<td>
#Html.DisplayFor(model=>item.Name)
</td>
<td>
#Html.DisplayFor(model=>item.RoleName)
</td>
</tr>
}
<tr>
<th>
<u>Invited Members</u>
</th>
</tr>
<tr>
<th>
ProjectID
</th>
<th>
Name
</th>
</tr>
#foreach(var item2 in Model.Where(m=>m.Status==0))
{
<tr>
<td>
#Html.DisplayFor(model=>item2.ProjectID)
</td>
<td>
#Html.DisplayFor(model=>item2.Name)
</td>
</tr>
}
<tr>
<td>
#Html.TextBoxFor(?)
</td>
<td>
<input type="submit" id="btnsearch" value="Search"/>
</td>
</tr>
</table>
}
viewmodel
public class _ContributeViewModel
{
public int UserID { get; set; }
[StringLength(20)]
public string Name { get; set; }
[StringLength(20)]
public string Email { get; set; }
[StringLength(20)]
public string Facebook { get; set; }
[StringLength(20)]
public string Twitter { get; set; }
[StringLength(20)]
public string LinkedIn { get; set; }
[StringLength(20)]
public string Github { get; set; }
[StringLength(50)]
public string Password { get; set; }
[StringLength(50)]
public string Photo { get; set; }
[StringLength(100)]
public string Address { get; set; }
[StringLength(50)]
public string PhoneNo { get; set; }
[StringLength(500)]
public string Other { get; set; }
public DateTime CreateDate { get; set; }
public int RoleID { get; set; }
public int ProjectID { get; set; }
[StringLength(20)]
public string RoleName { get; set; }
public int Status { get; set; }
}
Controller
[HttpGet]
public ActionResult Contribute(int? projectID)
{
PMSDBContext PMP = new PMSDBContext();
//List<_ContributeViewModel> cvm = new List<_ContributeViewModel>();
// _Contribute cv=new _Contribute();
// cvm = cv.GetMember();
List<_ContributeViewModel> result = new List<_ContributeViewModel>();
result = PMP.Relations
.Join(PMP.Roles, a => a.RoleID,
b => b.RoleID,
(a, b) => new { Relation = a, Role = b })
.Join(PMP.Users,
a => a.Relation.UserID,
c => c.UserID,
(a, c) => new { a.Relation, a.Role, Users = c })
.Where(a => a.Relation.ProjectID == 1)
.Select(a => new _ContributeViewModel
{
ProjectID = a.Relation.ProjectID,
RoleName = a.Role.RoleName,
Name = a.Users.Name,
Status = a.Relation.Status,
}
).ToList();
return View(result);
}
[HttpPost]
public ActionResult Contribute(_ContributeViewModel Model)
{
return View();
}
Problem i am facing is that..i cant use #Html.TextBoxFor(m=>Model.Name or Something) to pass textbox value to controller..it is because of List?but if i remove List<>..i get problems in foreach loop...Should i use partial view for this textbox? or is there any better ways than using partial views?Please Suggest...
You can use TextBox() this way:
#{
int index = 0;
}
#foreach(var item2 in Model.Where(m=>m.Status==0))
{
#Html.TextBox("Model["+index.ToString()+"].ProjectID",item2.ProjectID)
#Html.TextBox("Model["+index.ToString()+"].Name",item2.Name)
#{ index = index +1; }
}
You may also refer to this article
Simply create one new Model class, like:
public class _ContributeViewModel2
{
List<PMS.View_Model._ContributeViewModel> ContributeList { get; set; }
string SearchString { get; set; }
}
Pass this to your View and use like this,
#model _ContributeViewModel2
#{
ViewBag.Title = "Contribute";
}
#using (Html.BeginForm())
{
#Html.Partial("_Project")
#Html.ValidationSummary(true)
<table>
<tr>
<th>
<u>Current Members</u>
</th>
</tr>
<tr>
<th>
ProjectID
</th>
<th>
Name
</th>
<th>
Role
</th>
</tr>
#foreach(var item in Model.ContributeList.Where(m=>m.Status==1))
{
<tr>
<td>
#Html.DisplayFor(item.ProjectID)
</td>
<td>
#Html.DisplayFor(item.Name)
</td>
<td>
#Html.DisplayFor(item.RoleName)
</td>
</tr>
}
<tr>
<th>
<u>Invited Members</u>
</th>
</tr>
<tr>
<th>
ProjectID
</th>
<th>
Name
</th>
</tr>
#foreach(var item2 in Model.ContributeList.Where(m=>m.Status==0))
{
<tr>
<td>
#Html.DisplayFor(item2.ProjectID)
</td>
<td>
#Html.DisplayFor(item2.Name)
</td>
</tr>
}
<tr>
<td>
#Html.TextBoxFor(model=> m.SearchString)
</td>
<td>
<input type="submit" id="btnsearch" value="Search"/>
</td>
</tr>
</table>
}
Thank you.