Reputation: 1601
In my ASP.NET MVC application users can post projects and they will be store in the DB. As usual, there is an Index view for the projects where users can see the list of all the projects available, along with some action links beside them (Details/Apply).
When a user clicks on the "Apply" action link, he is asked to fill in some words about why he wants to participate (cover letter). After he submits, an Application is stored inside the database containing a unique ApplicationId
, the user's UserId
and the ProjectId
that he is applying to so I can keep track of all the applications.
public class Application
{
public int ApplicationId { get; set; }
public int ProjectId { get; set; }
public string UserId { get; set; }
public string CoverLetter { get; set; }
}
In the "Details" view, all the project's data is being displayed, and managed to get it to display all the cover letters and the userId's that applied for this project.
Cover letters:
@foreach (var item in Model.Applications)
{
<tr>
<td>
<br/>
@Html.DisplayFor(modelItem => item.CoverLetter) |
@Html.DisplayFor(modelItem => item.UserId) |
</td>
</tr>
}
The UserId
and CoverLetter
from the Application is retrieved successfully, however what I need is based on the UserId
to retrieve the user's name and email from the database.
Edit: here is the entire ProjectsController:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using System.Web.Security;
using Leepio.Models;
using Microsoft.ApplicationInsights.Web;
using Microsoft.AspNet.Identity;
namespace Leepio.Controllers
{
public class ProjectsController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: Projects
[Authorize(Roles = "companyRole, studentRole")]
public ActionResult Index(string SortOrder, string SortBy, string Page)
{
ViewBag.SortOrder = SortOrder;
ViewBag.SortBy = SortBy;
var projects = db.Projects.ToList();
var model = new ApplicationTwoViewModel
{
Model1 = new List<Project>(projects),
Model2 = new Application
{
UserId = User.Identity.GetUserId(),
ProjectId = 11,
CoverLetter = "asdf",
ApplicationId = 23,
}
};
switch (SortBy)
{
case "Title":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.Title).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.Title).ToList();
break;
default:
break;
}
break;
case "ApplicationDeadline":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.ApplicationDeadline).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.ApplicationDeadline).ToList();
break;
default:
break;
}
break;
case "Duration":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.Duration).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.Duration).ToList();
break;
default:
break;
}
break;
case "HourlyRate":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.HourlyRate).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.HourlyRate).ToList();
break;
default:
break;
}
break;
case "TotalProjectCost":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.TotalProjectCost).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.TotalProjectCost).ToList();
break;
default:
break;
}
break;
case "City":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.City).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.City).ToList();
break;
default:
break;
}
break;
case "RequiredPresencePercent":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.RequiredPresencePercent).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.RequiredPresencePercent).ToList();
break;
default:
break;
}
break;
case "Language":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.Language).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.Language).ToList();
break;
default:
break;
}
break;
case "RequiredSkills":
switch (SortOrder)
{
case "Asc":
projects = projects.OrderBy(x => x.RequiredSkills).ToList();
break;
case "Desc":
projects = projects.OrderByDescending(x => x.RequiredSkills).ToList();
break;
default:
break;
}
break;
default:
projects = projects.OrderBy(x => x.Title).ToList();
break;
}
ViewBag.TotalPages = Math.Ceiling(db.Projects.ToList().Count()/10.0);
int page = int.Parse(Page == null ? "1" : Page);
ViewBag.Page = page;
model.Model1 = projects;
model.Model1 = model.Model1.Skip((page - 1) * 10).Take(10).ToList();
return View(model);
}
private UserManager<IUser<> userManager;
// GET: Projects/Details/5
[Authorize(Roles = "companyRole, studentRole")]
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
if (project == null)
{
return HttpNotFound();
}
return View(project);
}
// GET: Projects/Create
[Authorize(Roles= "companyRole")]
public ActionResult Create()
{
return View();
}
// POST: Projects/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]
[Authorize(Roles = "companyRole")]
public ActionResult Create([Bind(Include = "UserId,ProjectId,Title,ApplicationDeadline,Duration,HourlyRate,TotalProjectCost,City,RequiredPresencePercent,Language,RequiredSkills,Description")] Project project)
{
if (ModelState.IsValid)
{
project.UserId = User.Identity.GetUserId();
db.Projects.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(project);
}
// GET: Projectts/Edit/5
[Authorize(Roles = "companyRole")]
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
if (project == null)
{
return HttpNotFound();
}
return View(project);
}
// POST: Projects/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]
[Authorize(Roles = "companyRole")]
public ActionResult Edit([Bind(Include = "ProjectId,UserId,Title,ApplicationDeadline,Duration,HourlyRate,TotalProjectCost,City,RequiredPresencePercent,Language,RequiredSkills,Description")] Project project)
{
if (ModelState.IsValid)
{
if (project.UserId == User.Identity.GetUserId())
{
db.Entry(project).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return HttpNotFound("Project is not yours!");
}
return View(project);
}
// GET: Projects/Delete/5
[Authorize(Roles = "companyRole")]
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
if (project == null)
{
return HttpNotFound();
}
return View(project);
}
// POST: Projects/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
[Authorize(Roles = "companyRole")]
public ActionResult DeleteConfirmed(int id)
{
Project project = db.Projects.Find(id);
if (project.UserId == User.Identity.GetUserId())
{
db.Projects.Remove(project);
db.SaveChanges();
}
else
{
return HttpNotFound("Project is not yours!");
}
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Do I actually need to change anything inside the ApplicationController
? I am not sure how to go about doing this.
Upvotes: 1
Views: 3054
Reputation: 1601
I found the solution, much more simple.
Inside the ProjectsController Details GET method :
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
var user = UserManager.FindByIdAsync(project.UserId);
ViewData["user"] = user.Result.Email;
if (project == null)
{
return HttpNotFound();
}
return View(project);
}
Basically retrieving the entire User entity inside the 'user' var. Then I just send it to the view with ViewData["user"] = user.Result.Email;
@foreach (var item in Model.Applications)
{
<tr>
<td>
<br />
@Html.DisplayFor(modelItem => item.CoverLetter) |
@Html.DisplayFor(modelItem => @ViewData["user"])
</td>
</tr>
}
I initialized the UserManager as so:
private ApplicationDbContext db = new ApplicationDbContext();
public ProjectsController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public ProjectsController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager { get; set; }
Upvotes: 0
Reputation: 247008
You may not need to modify your ApplicationController
. After finding the Project
, use Project.UserId
to get the associated User
from the Identity framework like...UserManager.FindByIdAsync(userId)
.
You'll need to modify your returned model to pass that information back to your view, but it is possible to achieve what you are requesting.
Given your current Application
class you can create a new model from scratch or via inheritance, adding the properties you need for your view...
public class ProjectDetailsApplicationModel : Application {
public string UserName { get; set; }
public string Email { get; set; }
}
...The above show the model via inheritance.
You can then create a view model for your view that holds all the information you need to show the needed details...
public class ProjectDetailsModel {
public Project Project { get; set; }
public IEnumerable<ProjectDetailsApplicationModel> Applications { get; set; }
}
Now you indication that you are using Asp.Net-Identity framework so given that assumption your ProjectsController
can be modified to something like this...
public class ProjectsController : Controller {
private ApplicationDbContext db;
private ApplicationUserManager userManager;
public ProjectController() {
this.userManager = new ApplicationUserManager();
this.db = new ApplicationDbContext();
}
//...other code removed for brevity
public async Task<ActionResult> Details(int? id) {
if (id == null) {
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Project project = db.Projects.Find(id);
if (project == null) {
return HttpNotFound();
}
//construct model...
var model = new ProjectDetailsViewModel {
Project = project,
Applications = await BuildApplicationModels(project.Applications)
}
return View(model);
}
private async Task<IEnumerable<ProjectDetailsApplicationModel>> BuildApplicationModels(IEnumerable<Application> applications) {
List<ProjectDetailsApplicationModel> result = new List<ProjectDetailsApplicationModel>();
foreach (var application in applications) {
var model = new ProjectDetailsApplicationModel {
ApplicationId = application.ApplicationId,
ProjectId = application.ProjectId,
UserId = application.UserId,
CoverLetter = application.CoverLetter
};
var user = await userManager.FindByIdAsync(application.UserId);
if (user != null) {
model.UserName = user.UserName;
model.Email = user.Email;
}
result.Add(model);
}
return result;
}
}
You can then reference the User's name and email in the view...
@model: ProjectDetailsModel
<!--...other markup...-->
Cover letters:
@foreach (var item in Model.Applications)
{
<tr>
<td>
<br/>
@Html.DisplayFor(modelItem => item.CoverLetter) |
@Html.DisplayFor(modelItem => item.UserName) |
@Html.DisplayFor(modelItem => item.Email) |
</td>
</tr>
}
Upvotes: 1