How to display data from current user that's logged in - asp.net-mvc

I want to display the events of the user that is currently logged on
How do I do that?
Here is my code:
This is my Model
public Event()
{
Venues = new HashSet<Venue>();
Ratings = new HashSet<Rating>();
}
public int EventID { get; set; }
[Required]
[StringLength(50)]
[Display(Name="Event Name")]
public string EventName { get; set; }
[Required]
[StringLength(100)]
[Display(Name = "Event Description")]
public string EventDesc { get; set; }
[Column(TypeName = "image")]
[Display(Name = "Event Logo")]
public byte[] EventLogo { get; set; }
[StringLength(50)]
[Display(Name = "Event Location")]
public string EventLocation { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
Here is my controller:
public ActionResult ManageEvent()
{
if (!User.Identity.IsAuthenticated)
{
return RedirectToAction("Login", "Account");
}
var events = db.Events;
return View(events.ToList());
}
Here is my View:
#model IEnumerable<Project_Touchee.Models.Event>
#{
ViewBag.Title = "Manage Events";
}
<h2>Manage All Events</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.EventLogo)
</th>
<th>
#Html.DisplayNameFor(model => model.EventName)
</th>
<th>
#Html.DisplayNameFor(model => model.EventDesc)
</th>
<th>
#Html.DisplayNameFor(model => model.EventLocation)
</th>
#foreach (var item in Model)
{
<tr>
<td>
#{
byte[] eventt = item.EventLogo;
string imageSrc = null;
if (item.EventLogo != null)
{
MemoryStream ms = new MemoryStream();
ms.Write(eventt, 0, eventt.Length);
string imageBase64 = Convert.ToBase64String(ms.ToArray());
imageSrc = string.Format("data:image/index;base64,{0}", imageBase64);
}
}
<img src="#imageSrc" width="100" height="100" />
</td>
<td>
#Html.DisplayFor(modelItem => item.EventName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EventDesc)
</td>
<td>
#Html.DisplayFor(modelItem => item.EventLocation)
</td>
This should only display the events that the current user created.

First, you need to get a copy of the current user:
var user = UserManager.FindById(User.Identity.GetUserId());
Then, you need to query the events using that:
var events = db.Events.Where(m => m.AspNetUser == user);
You can make your life simpler by adding a navigation property to AspNetUser for events:
public virtual ICollection<Event> Events { get; set; }
Then, you can just use: user.Events

Related

FullName from Identity is not working asp .net core 3.0

I am working on a small project and trying to display the fullname (which added by me on in ApplicationUser Model inhireted from IdentityUser) and below the Model:
public class ApplicationUser : IdentityUser
{
public int PersonnalNumber { get; set; }
public string FullName { get; set; }
}
here is SystemDetails Model have relationship with Application User:
public class SystemDetails
{
[Key]
public int Id { get; set; }
[Required]
[Display(Name = "System Name")]
public string SystemName { get; set; }
[Required]
[Display(Name = "Admin Name")]
public string SystemAdminId { get; set; }
public string ServerNames { get; set; }
[ForeignKey("SystemAdminId")]
public virtual ApplicationUser ApplicationUser { get; set; }
}
and here is the Index View:
#if (Model.Count() > 0)
{
<table class=" table table-striped border">
<tr class="table-secondary">
<th>
#Html.DisplayNameFor(m => m.SystemName)
</th>
<th>
#Html.DisplayNameFor(m => m.SystemAdminId)
</th>
<th></th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(m => item.SystemName)
</td>
<td>
#Html.DisplayFor(m => item.ApplicationUser.FullName)
</td>
<td>
<partial name="_TableButtonPartial" model="#item.Id" />
</td>
</tr>
}
Everything working fine except that FullName is not displayed on index page, I can display SystemAdminId which is the registered user Id but when i try to display the FullName using Applicationuser.FullName it is not displaying any thing! it is saved correctly on the database when I create record on SystemDetails Controller as below:
SystemAdminId
Here is create action:
[HttpPost,ActionName("Create")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreatePost()
{
List<ApplicationUser> userList = new List<ApplicationUser>();
if (!ModelState.IsValid)
{
return NotFound();
}
userList = await (from user in _db.ApplicationUser select user).ToListAsync();
ViewBag.usersList = userList;
_db.SystemDetails.Add(SystemDetails);
await _db.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
Appreciating any help
In controller , when querying the SystemDetails list you should load the related ApplicationUser :
using Microsoft.EntityFrameworkCore;
var result = _dbContext.SystemDetails.Include(f => f.ApplicationUser).ToList();

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??

Join table in Entity Framework and display other column

I'm trying to make my list to show data from another column instead of its ID, currently they are showing like so:
This is what I work out so far:
Controller:
public class CompanyAdmin
{
public string Id { get; set; }
[Required(AllowEmptyStrings = false)]
[Display(Name = "Company Name")]
public string CompanyName { get; set; }
public virtual List<Certificate> Certificates { get; set; }
public class Certificate
{
[Key]
[Display(Name = "Certificate No.")]
public string CertNo { get; set; }
[Display(Name = "Company")]
public IEnumerable<SelectListItem> Companies { get; set; }
[Required]
public string Company { get; set; }
[Display(Name = "User")]
public IEnumerable<SelectListItem> UserList { get; set; }
[Required]
public string User { get; set; }
public string UploadedBy { get; set; }
[Display(Name = "Description")]
public string CertDescription { get; set; }
[Display(Name = "File Location")]
public string CertFileLocation { get; set; }
[Display(Name = "Last Modified")]
public DateTime LastModifiedDate { get; set; }
}
public class CertificateViewModel
{
[Display(Name = "Certificate No.")]
public string CertNo { get; set; }
public string User { get; set; }
[Display(Name = "User")]
public string UserName { get; set; }
public string Company { get; set; }
[Display(Name = "Company")]
public string CompanyName { get; set; }
[Display(Name = "Description")]
public string CertDescription { get; set; }
[Display(Name = "Last Modified")]
public DateTime LastModifiedDate { get; set; }
}
Here is my controller:
public ActionResult Index()
{
if (User.IsInRole("Admin"))
{
IEnumerable<CertificateViewModel> model = null;
model = (from c in db.CertificateDB
join u in db.Users on c.User equals u.Id
join d in db.CompanyDB on c.Company equals d.Id
select new CertificateViewModel
{
CertNo = c.CertNo,
UserName = u.UserName,
CompanyName = d.CompanyName,
CertDescription = c.CertDescription,
LastModifiedDate = c.LastModifiedDate
}
);
return View(model);
}
else
{
return RedirectToAction("Index", "Home");
}
}
and the view:
#model IEnumerable<IdentitySample.Models.CertificateViewModel>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.CertNo)
</th>
<th>
#Html.DisplayNameFor(model => model.Company)
</th>
<th>
#Html.DisplayNameFor(model => model.User)
</th>
<th>
#Html.DisplayNameFor(model => model.CertDescription)
</th>
<th>
#Html.DisplayNameFor(model => model.LastModifiedDate)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.CertNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.Company)
</td>
<td>
#Html.DisplayFor(modelItem => item.User)
</td>
<td>
#Html.DisplayFor(modelItem => item.CertDescription)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastModifiedDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.CertNo }) |
#Html.ActionLink("Details", "Details", new { id = item.CertNo }) |
#Html.ActionLink("Delete", "Delete", new { id = item.CertNo })
</td>
</tr>
}
</table>
My Context:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
static ApplicationDbContext()
{
// Set the database intializer which is run once during application start
// This seeds the database with admin user credentials and admin role
Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
}
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
string errorMessages = string.Join("; ", ex.EntityValidationErrors.SelectMany(x => x.ValidationErrors).Select(x => x.PropertyName + ": " + x.ErrorMessage));
throw new DbEntityValidationException(errorMessages);
}
}
public DbSet<CompanyAdmin> CompanyDB { get; set; }
public DbSet<Certificate> CertificateDB { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
But the results keep coming up empty for the 2 join columns, please see screenshot here
Any idea what I've done wrong?
In your query you populate property CompanyName, but in your view you render property Company. Same goes for User in view vs UserName in a query.
Also I recommend adding .ToList() just before you pass the model to your view - this will make sure data is extracted from DB into objects before it is passed to your view:
model = (from c in db.CertificateDB
join u in db.Users on c.User equals u.Id
join d in db.CompanyDB on c.Company equals d.Id
select new CertificateViewModel
{
CertNo = c.CertNo,
UserName = u.UserName,
CompanyName = d.CompanyName,
CertDescription = c.CertDescription,
LastModifiedDate = c.LastModifiedDate
}
).ToList();
You are setting UserName and CompanyName property for your CertificateViewModel in controller action:
UserName = u.UserName,
CompanyName = d.CompanyName,
while in View you are using Company and User property:
<td>
#Html.DisplayFor(modelItem => item.Company)
</td>
<td>
#Html.DisplayFor(modelItem => item.User)
</td>
So you either need to set the Company and User property of your view model in controller or use CompanyName and UserName for rendering in View, if you change the view, change it to use the correct properties :
<td>
#Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
#Html.DisplayFor(modelItem => item.UserName)
</td>

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>
}

Proper way to bind the model to view in MVC?

Im newbie to mvc.I have a menusettings page where user can add menu according to his role.For that I want to create a view.How can I bind the model to view properly so that i can save the settings.My concern is inorder to access ienumerable item in the viewmodel,viewmodel should also be ienumerable.Here i cannot convert the viewmodel to ienumerable.
Any help will be greatly appreciated
ModelClass is
public partial class Role
{
public int Id { get; set; }
public string RoleName { get; set; }
public Nullable<int> ParentID { get; set; }
public virtual ICollection<MenuRole> MenuRoles { get; set; }
}
public partial class Menu
{
public int Id { get; set; }
public string MenuName { get; set; }
public string NavigateUrl { get; set; }
public Nullable<int> ParentID { get; set; }
public virtual ICollection<MenuRole> MenuRoles { get; set; }
}
ViewModel Is
public class MenuRoleVM
{
public int? RoleId { get; set; }
public SelectList RoleList { get; set; }
public IEnumerable<Menu> MenuList { get; set; }
}
My controller is
public class MenuSettingsController : Controller
{
public ActionResult Add()
{
var _menuRoleVM = new MenuRoleVM
{
RoleList = new SelectList(_db.Roles.ToList(), "Id", "RoleName"),
MenuList = _db.Menus
.Where(m => m.NavigateUrl != "#").ToList()
};
return View(_menuRoleVM);
}
}
Below example will help. Here, I have the model ContactModel with properties - FirstName, LastName and Email.
#model IEnumerable<CrazyContacts.Models.ContactModel>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.LastName)
</th>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
Thanks for your input #Stephen.
I got the code running by the adding the view as below
#foreach (var item in Model.MenuList.Select((x, i) => new {Data=x,Index=i }))
{
<tr>
<td>#(item.Index+1)</td>
<td>#item.Data.MenuName</td>
</tr>
}

Resources