Display Country Entity inside the Index - asp.net-mvc

I have an entity called Fixture, and basically I want to display some fixtures on the page.
My Model is as follows :-
public class Fixture
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int FixtureId { get; set; }
[Display(Name = "Fixture Date")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime? FixtureDate { get; set; }
public DateTime? FixtureTime { get; set; }
public int? CityId { get; set; }
public City City { get; set; }
public int CountryIdA { get; set; }
public int CountryIdB { get; set; }
public int? ScoreA { get; set; }
public int? ScoreB { get; set; }
public Round Round { get; set; }
public int? RoundId { get; set; }
public List<Scorer> Scorers { get; set; }
}
and my ViewModel is as follows :-
public class FixtureViewModel
{
public Fixture Fixture { get; set; }
public IEnumerable<Fixture> FixtureList { get; set; }
public IEnumerable<GroupCountry> GroupCountryList { get; set; }
public IEnumerable<Group> GroupList { get; set; }
public string CountryNameA { get; set; }
public string CountryNameB { get; set; }
}
and I am displaying them in this index page :-
<table>
<tr>
<th>
#Html.DisplayName("Date")
</th>
<th>
#Html.DisplayName("Country A")
</th>
<th>
#Html.DisplayName("Country A")
</th>
<th>
#Html.DisplayName("Score A")
</th>
<th>
#Html.DisplayName("Score B")
</th>
<th>
#Html.DisplayName("Round")
</th>
<th></th>
</tr>
#foreach (Fixture item in Model.FixtureList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FixtureDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.CountryIdA)
</td>
<td>
#Html.DisplayFor(modelItem => item.CountryIdB)
</td>
<td>
#Html.DisplayFor(modelItem => item.ScoreA)
</td>
<td>
#Html.DisplayFor(modelItem => item.ScoreB)
</td>
<td>
#Html.DisplayFor(modelItem => item.Round.RoundName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new {id = item.FixtureId}) |
#Html.ActionLink("Details", "Details", new {id = item.FixtureId}) |
#Html.ActionLink("Delete", "Delete", new {id = item.FixtureId})
</td>
</tr>
}
</table>
Now in the index page, I wish to display something like this :-
<td>
#Html.DisplayFor(modelItem => item.CountryIdA.Country.CountryName)
</td>
<td>
#Html.DisplayFor(modelItem => item.CountryIdB.Country.CountryName)
</td>
How can I achieve that?
I added a navigation item Country in the Model, however I still cannot display the correct CountryName.
Thanks for your help and time

Well CountryIdA and CountryIdB are just Integers. If you are trying to say...
Find a fixture with CountryIdA/B, then get it's Country, and then CountryName
then this is not appropriate to put in a view. Your view should not handle any data access, that is the job of your controller/model. I would suggest adding two Country properties to your view model, one for IdA and one for IdB. Then you can populate these in your controller action and have access to them in your view.
Your controller might look something like...
ViewModel.CountryA = Countries.Where(x => x.CountryID = ViewModel.CountryIdA)

You can extend Fixture in your model by creating a partial class Fixture in the same namespace, create two custom properties CountryIdA/B that does a lookup for the currect IDs.

Related

How to Retrieve data from multiple table in a single view in asp.net core 6 mvc code first approach

I have Course and Student model with foreign key. I want to show student details in index view with CourseName and CourseId.
This is Course Model
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace JECRC.Models
{
public class Course
{
[Key]
public int CourseId { get; set; }
[Required]
public string CourseName { get; set; }
public List<Student> Students { get; set; }
public Faculty Faculty { get; set; }
}
}
This is Student Model
using System.ComponentModel.DataAnnotations;
namespace JECRC.Models
{
public class Student
{
[Key]
public int StudentId { get; set; }
[Required]
public string StudentName { get; set; }
[Required]
public string Class { get; set; }
public int CourseId { get; set; }
public Course Course { get; set; }
}
}
This is my Student Controller
using JECRC.Context;
using JECRC.Models;
using Microsoft.AspNetCore.Mvc;
namespace JECRC.Controllers
{
public class StudentController : Controller
{
private readonly DataContext dc;
public StudentController(DataContext dc)
{
this.dc = dc;
}
public IActionResult Index()
{
IEnumerable<Student> students = dc.Students;
return View(students);
}
}
}
and this is my Index View
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.StudentId)
</th>
<th>
#Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
#Html.DisplayNameFor(model => model.Class)
</th>
#Html.DisplayNameFor(model => model.Course.CourseName)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.StudentId)
</td>
<td>
#Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Class)
</td>
<td>
#Html.DisplayFor(modelItem => item.Course.CourseName)
</td>
</tr>
}
</tbody>
</table>
I know I have to join these two table Student and Course in Student controller but i don't know how to do it, please help me to solve this problem,I will be very thank full for this.

ASP.NET MVC limit Table view depending on user role

So I'm building a web app for tracking holidays across a company that has different sites. I need to display list of employees on my admin page but I only want Managers/Admins to view the employee list related to them based on their sites (they may have one or many).
On my Admin page, I have created a table of employees from my database, which displays all employees and links to their details on each row.
Controller :
public ActionResult Index(int? page, string searchString)
{
var employees = db.Employees.Include(e => e.Area).Include(e => e.Discipline).Include(e => e.Shift).Include(e => e.Site).Include(e => e.UserRole);
return View(employees.ToList().ToPagedList(page ?? 1, 10 ));
}
Model:
public partial class Employee
public Employee()
{
this.HolidayRequestForms = new HashSet<HolidayRequestForm>();
}
public int EmployeeID { get; set; }
public string FullName { get; set; }
[Required(ErrorMessage = "This Field is Required")]
public string EmailID { get; set; }
[Required(ErrorMessage = "This Field is Required")]
public string Password { get; set; }
public System.DateTime StartDate { get; set; }
public int RoleID { get; set; }
public int ShiftID { get; set; }
public int AreaID { get; set; }
public int DisciplineID { get; set; }
public int SiteID { get; set; }
public int ALCategory { get; set; }
public Nullable<int> HoursTaken { get; set; }
public Nullable<int> AwardedLeave { get; set; }
public Nullable<int> TotalHoursThisYear { get; set; }
public int HoursCarriedForward { get; set; }
public Nullable<int> EntitlementRemainingThisYear { get; set; }
public string Comments { get; set; }
public int SickLeaveTaken { get; set; }
public Nullable<int> SickLeaveEntitlement { get; set; }
public Nullable<int> SickLeaveEntitlementRemaining { get; set; }
public int StudyLeaveEntitlement { get; set; }
public int StudyLeaveTaken { get; set; }
public Nullable<int> StudyLeaveRemaining { get; set; }
public int ExamLeaveTaken { get; set; }
public int ForceMajeure { get; set; }
public int BereavementLeaveTaken { get; set; }
public int MaternityLeaveTaken { get; set; }
public int ParentalLeaveTaken { get; set; }
public int AdoptionLeaveTaken { get; set; }
public string LoginErrorMessage { get; set; }
public virtual Area Area { get; set; }
public virtual Discipline Discipline { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<HolidayRequestForm> HolidayRequestForms { get; set; }
public virtual Shift Shift { get; set; }
public virtual Site Site { get; set; }
public virtual UserRole UserRole { get; set; }
}
And View (just the table section):
<table class="table table-striped">
<tr>
<th>
Name
</th>
<th>
Start Date
</th>
<th>
Area
</th>
<th>
Discipline
</th>
<th>
Site Name
</th>
<th>
AL Category
</th>
<th>
Hours CF
</th>
<th>
Awarded Leave
</th>
<th>
Total Hours This Year
</th>
<th>
Hours Taken
</th>
<th>
Hours Remaining
</th>
<th>
Role
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FullName)
</td>
<td>
#Html.DisplayFor(modelItem => item.StartDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Area.Area1)
</td>
<td>
#Html.DisplayFor(modelItem => item.Discipline.Discipline1)
</td>
<td>
#Html.DisplayFor(modelItem => item.Site.SiteName)
<td>
#Html.DisplayFor(modelItem => item.ALCategory)
</td>
<td>
#Html.DisplayFor(modelItem => item.HoursCarriedForward)
</td>
<td>
#Html.DisplayFor(modelItem => item.AwardedLeave)
</td>
<td>
#Html.DisplayFor(modelItem => item.TotalHoursThisYear)
</td>
<td>
#Html.DisplayFor(modelItem => item.HoursTaken)
</td>
<td>
#Html.DisplayFor(modelItem => item.EntitlementRemainingThisYear)
</td>
<td>
#Html.DisplayFor(modelItem => item.UserRole.RoleName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.EmployeeID }, new { #class = "btn-xs btn-warning glyphicon glyphicon-pencil" })
#Html.ActionLink("Details", "Details", new { id = item.EmployeeID }, new { #class = "btn-xs btn-info glyphicon glyphicon-info-sign" })
#Html.ActionLink("Delete", "Delete", new { id = item.EmployeeID }, new { #class = "btn-xs btn-danger glyphicon glyphicon-trash" })
</td>
</tr>
}
</table>
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }))
I'd like it so that only managers/Admins assigned to certain sites could only view those sites and none else. Regular Users don't have access to this page.
Is this possible to do in mvc??

Save the List value during the post back, its get cleared when i try to access the list after clicking the button each time in MVC

Controller:
List<EmployeeSkill> emp = new List<EmployeeSkill>();
public ActionResult viewskills(EmployeeSkill objskillset)
{
emp .Add(objskillset);
return PartialView("_SkillListPartial", objskillset);
}
Model:
public int EmployeeID { get; set; }
[Required(ErrorMessage = "Please Enter Skill")]
public string SkillName { get; set; }
[Display(Name = "Experience (In Months)")]
[Required(ErrorMessage = "Please Enter Experience(In Months)")]
public Nullable<byte> ExperienceInMonths { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> CreatedDate { get; set; }
public string ModifiedBy { get; set; }
public Nullable<System.DateTime> ModifiedDate { get; set; }
public Nullable<bool> IsActive { get; set; }
public virtual EmployeeDetail EmployeeDetail { get; set; }
View:
model IEnumerable<CISSEC.Models.EmployeeSkill>
<table class="table">
<tr>
<th> #Html.DisplayNameFor(model => model.SkillName) </th>
<th> #Html.DisplayNameFor(model => model.ExperienceInMonths)</th>
</tr>
#foreach (var item in Model) {
<tr>
<td> #Html.DisplayFor(modelItem => item.SkillName) </td>
<td> #Html.DisplayFor(modelItem => item.ExperienceInMonths) </td>
</tr>
}
</table>
Your list is not posted back because you do not render <input> elements for the properties of the list items. Use HiddenFor to render the inputs. Use a for loop so the modelbinder receives the correct index of the list items.
#for (var i = 0; i < Model.Count(); i++) {
<tr>
<td> #Html.HiddenFor(m => m[i].SkillName) </td>
<td> #Html.HiddenFor(m=> m[i].ExperienceInMonths) </td>
</tr>
}

Insert value on different models in one view MVC 4

I have a model course, component, subcomponent and evaluation:
public class Course
{
public virtual int CourseId { get; set; }
(...)
public virtual List<Component> Components { get; set; }
public virtual List<UserCourse> Users { get; set; }
}
public class Component
{
public virtual int ComponentId { get; set; }
public virtual string Type { get; set; }
public virtual string Name { get; set; }
public virtual Course Course { get; set; }
public virtual List<Subcomponent> Subcomponents { get; set; }
}
public class Subcomponent
{
public virtual int SubcomponentId { get; set; }
public virtual int ComponentId { get; set; }
public virtual string TypeSub { get; set; }
public virtual string NameSub { get; set; }
(...)
public virtual int ParentId { get; set; }
public virtual Subcomponent Parent { get; set; }
public virtual List<Subcomponent> Childs { get; set; }
public virtual Component Component { get; set; }
}
public class Evaluation
{
public virtual int EvaluationId { get; set; }
public virtual int ComponentId { get; set; }
public virtual Component Component { get; set; }
public virtual int UserCourseId { get; set; }
public virtual UserCourse User { get; set; }
public virtual int Grade { get; set; }
}
I need to give a grade to each subcomponent (or component if the component doesn't have subcomponents) to each user.
First i have a view that shows the users and the grades already given, like an index:
#model SGP.Models.Course
<table>
<tr>
<th>
Users
</th>
<th>
Grades
</th>
</tr>
#foreach (var x in Model.Users)
{
<tr>
<td>
#Html.DisplayFor(modelItem => x.User.UserName)
</td>
#foreach (var y in x.Evaluation)
{
<td>
<table>
<tr>
<td>
<b>#Html.DisplayFor(modelItem => y.Component.NameComp)</b>
</td>
</tr>
<tr>
<td>
#Html.DisplayFor(modelItem => y.Grade)
</td>
</tr>
</table>
</td>
}
<td>
#Html.ActionLink("Give grade", "Comps", "Evaluation", new { id = x.UserCourseId }, null)
</td>
</tr>
}
</table>
Then when press "Give grade", i have a search box to select the component wich the grade will be given.
The search will give a list of subcomponents of that component. Each component can have one or more subcomponents so the final grade to the component is the average of the subcomponents grades.
The view of the subcomponents:
#model SGP.Models.Component
<table>
<tr>
<th>
#Html.DisplayFor(model => model.NameComp)
</th>
<th>
Grade
</th>
</tr>
#foreach (var item in Model.Subcomponents) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.NameSub)
</td>
<td>
???????
</td>
</tr>
}
</table>
But in this view i need to get the UserCourseId previously selected and give a grade to the user in the selected subcomponent. How can i do that?
Thanks
EDIT:
Give grade:
#using (Html.BeginForm("ListaSubs", "Evaluation", FormMethod.Post))
{
<table>
<tr>
<th>
#Html.TextBox("text")
</th>
<td>
<input type="submit" id="ButtonSearch" value="Search" />
</td>
</tr>
</table>
}
And controller:
[HttpPost, ActionName("ListaSubs")]
public ActionResult ListaSubs(string text)
{
var util = (db.Subcomponents.Where(m =>
m.ComponentId.Equals(text)));
return View("view", util);
}
What I do in this case, is to define a wrapper class and use it for view's model. Something like this:
public class MyWrapperClass
{
public Course _Course { get; set; }
public Component _Component { get; set; }
...
}
Then in your view, you define your model as:
#model MyWrapperClass
For some controls you can simply use the following format for the properties:
#Html.HiddenFor(model => model._Course.CourseId)
But in some cases, you probably have to create EditorTemplate or DisplayTemplate for each subclass and use the templates in the view.
To use Editor template, you need to use a UIHint attribute in the class definition.
Here is some links on how to use editor template in razor:
How to add and use a razor editor template
https://www.simple-talk.com/dotnet/asp-net/extending-editor-templates-for-asp-net-mvc/

Filtering a view with 2 tables with same database tables

I have created a view which contains 2 tables.
What I want is to filter each table data according to their transaction type for example table1 should show only Payables List and table2 should show only Reciveable List.
here is the code
Note When I navigate to the view server shows me The resource cannot be found.other views are fine. here is my code.
My project has BOL(EF Model) BLL(Business object) DAL(Data Access layer) and my main Mvc project
View
#model shinwari_traders.Areas.Shinwari.Models.ADetailsVm
#{
ViewBag.Title = "Index";
}
<h2>AccountDetails</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table id="Payables" class="table">
<tr>
<th>
Date
</th>
<th>
Discription
</th>
<th>
Amount
</th>
</tr>
#foreach (var item in Model.Payables)
{
<tr>
<td>
#item.Date
</td>
<td>
#item.Discription
</td>
<td>
#item.Amount
</td>
</tr>
}
</table>
<table id="Reciveables" class="table">
<tr>
<th>
Date
</th>
<th>
Discription
</th>
<th>
Amount
</th>
</tr>
#foreach (var item in Model.Reciveables)
{
<tr>
<td>
#item.Date
</td>
<td>
#item.Discription
</td>
<td>
#item.Amount
</td>
</tr>
}
</table>
Controller
public class AccountDetailsController : Controller
{
private TransictionBs objbs;
public AccountDetailsController()
{
objbs = new TransictionBs(int accountid);
}
// GET: Shinwari/AccountDetails
public ActionResult Index(int accountid)
{ var v= new ADetails();
v.Payable = objbs.GetALL().Where(p => p.AId==accountid&& p.tbl_TransictionType.Type.Contains("Payable"));
v.Reciveable = objbs.GetALL().Where(r => r.AId==accountid && r.tbl_TransictionType.Type.Contains("Reciveable"));
return View(v);
}
}
}
Model Class
public class ADetailsVm
{
public List<BOL.tbl_Transiction> Payables { get; set; }
public List<BOL.tbl_Transiction> Reciveables { get; set; }
}
DatabaseTable
public partial class tbl_Transiction
{
public int TId { get; set; }
public Nullable<System.DateTime> Date { get; set; }
public Nullable<int> AId { get; set; }
public string Discription { get; set; }
public Nullable<double> PKR { get; set; }
public Nullable<double> Rate { get; set; }
public Nullable<double> Amount { get; set; }
public Nullable<int> TTId { get; set; }
public virtual tbl_Accounts tbl_Accounts { get; set; }
public virtual tbl_TransictionType tbl_TransictionType { get; set; }
}
You need a new view model with 2 collection properties one for each collection.
public class AccountDetailsVm
{
public List<BOL.tbl_Transiction> Reciveable {set;get;}
public List<BOL.tbl_Transiction> Payable {set;get;}
}
And in your GET action, create an object of this view model, fill these 2 properties.
public ActionResult Index(int accountid)
{
var v=new AccountDetailsVm();
//Load both the collection properties
v.Payables = objbs.GetALL()
.Where(p => p.AId==accountid && p.tbl_TransictionType.Type.Contains("Payable"));
v.Reciveable = objbs.GetByID(accountid).tbl_TransictionType.Type.Contains("Reciveable");
return View(v);
}
And your view is bound to the new view model. I just added the minimal code here. You can convert the rendering to a table.
#model AccountDetailsVm
<h1>Reciveable</h1>
#foreach(var item in Model.Reciveable)
{
<p>#item.Amount</p>
}
<h1>Payable</h1>
#foreach(var item in Model.Payable)
{
<p>#item.Amount</p>
}

Resources