Display message with my user id - it will not present it - asp.net-mvc

Right now I am working to create a messaging system to the website, but when I have to pull at it is sent to me and from me, it will not display content on the page.
there mind if I say that it should only take one of them, so accepterer it is perfectly fine.
It's making error here
[HttpGet]
public ActionResult besked(int id)
{
DataLinqDB db = new DataLinqDB();
UnderviserViewModel Model = new UnderviserViewModel();
//Brugerid :)
int userid = Helper.BrugerInformation.SessionVale.SessionBrugerid();
//Det som er blevet sendt til mig!
var ViewBeskederFrom = db.MessageTeachers.Where(i => i.id == id && i.fk_userTo == userid || i.fk_userFrom == userid).ToList();
if (ViewBeskederFrom != null)
{
Model.BeskederFrom = ViewBeskederFrom.ToList();
}
else
{
return RedirectToAction("Indbakke");
}
return View(Model);
}
It works fine if I do it like this.
var ViewBeskederFrom = db.MessageTeachers.Where(i => i.id == id && i.fk_userTo == userid || i.fk_userFrom == userid).ToList();
How can it be that it will not present it if I'm sender or recipient of the message end?
Database here (i have 316 userid)
UPDATE
[HttpGet]
public ActionResult besked(int id)
{
DataLinqDB db = new DataLinqDB();
UnderviserViewModel Model = new UnderviserViewModel();
//Brugerid :)
int userid = Helper.BrugerInformation.SessionVale.SessionBrugerid();
//Det som er blevet sendt til mig!
var ViewBeskederFrom = db.MessageTeachers.FirstOrDefault(i => i.id == id);
if (ViewBeskederFrom != null)
{
List<MessageTeacher> list = db.MessageTeachers.Where(i => i.id == id && i.fk_userTo == userid || i.fk_userFrom == userid).ToList();
if (list != null)
{
Model.BeskederFrom = list.ToList();
}
}
else
{
return RedirectToAction("Indbakke");
}
return View(Model);
}

Because you have an AND condition
i.fk_userTo == userid && i.fk_userFrom == userid
That means you need to have records with both fk_userTo and fk_userFrom column having the same userId value. From your screenshot you do not have such records.
You should be doing the OR condition which will give you either messages you sent or messages sent to you by some other user
i.fk_userTo == userid || i.fk_userFrom == userid
Also, your first if condition( checking the record id value against the id parameter of the action method) is probably going to give you only one record assuming id is the primary key of the table. So the result you are getting in ViewBeskederFrom variable will be List with maximum of one record.

Related

How to Detect state change in database table and add a schedule function to run at a specific time?

Let’s say I have a website where users can create questionnaires(Surveys) that get stored in the database for their users to answers the questions. My idea was to send an email notification to their users when the questionnaire has been changed for example a new question being added to the questionnaire.
However, to avoid send email every two minutes in case the user keeps on editing the questionnaire, I have created a temporary table ("LoggedSurveyUpdate") which will keep a record on when the questionnaire has been edited. Now the challenge that I am facing is that I would like the email notification to be sent an hour after the last questionnaire has been edited.
I hope this made sense.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(SurveyVM vm)
{
if (ModelState.IsValid)
{
try
{
bool readyToPublish = false;
if (vm.Survey.Publish)
{
readyToPublish = surveyLogic.CheckIfReadyToPublish(vm.Survey);
if (readyToPublish)
{
// User currentUser = userLogic.GetBy(x => x.UserID == vm.User.UserID);
Survey survey = surveyLogic.GetBy(x => x.SurveyName == vm.Survey.SurveyName && x.CustomerID == vm.Survey.CustomerID && x.SurveyID != vm.Survey.SurveyID).SingleOrDefault();
if (survey == null)
{
surveyLogic.Update(vm.Survey);
surveyLogic.SuveyUpdate(vm.Survey);
}
}
catch (Exception e)
{
vm.CategoryOptions = CategoryOptionsHelper.BuildCategoryOptions(vm.Survey.CustomerID, false);
TempData["Failure"] = "Edit Failed. Please Review Your Selections and Try Again.";
return View(vm);
}
}
}
Where data gets inserted in temporary table
public void SuveyUpdate(Survey survey)
{
using (ManageLoggedSurveyUpdate updateLogic = new ManageLoggedSurveyUpdate(ref base.Uow))
using (ManageSurvey surveyLogic = new ManageSurvey(ref base.Uow))
using (ManageLoggedSurveyUpdate loggedSurveyUpdate = new ManageLoggedSurveyUpdate(ref base.Uow))
{
Survey surveys = surveyLogic.GetBy(x => x.SurveyID == survey.SurveyID && x.Publish == survey.Publish).SingleOrDefault();
if (surveys == null)
{
LoggedSurveyUpdate newupdte = new LoggedSurveyUpdate()
{
SurveyID = survey.SurveyID,
Active = true,
SurveyEdited = DateTime.Now,
UserID = (int)System.Web.HttpContext.Current.Session["UserID"],
};
loggedSurveyUpdate.Insert(newupdte);
}
else {
LoggedSurveyUpdate newupdte = new LoggedSurveyUpdate()
{
SurveyID = survey.SurveyID,
Active = true,
SurveyEdited = DateTime.Now,
UserID = (int)System.Web.HttpContext.Current.Session["UserID"],
};
loggedSurveyUpdate.Update(newupdte);
}
}
}

System.NotSupportedException in Entity Framework (ASP.NET MVC)

I have an ASP.NET MVC5 project with Entity Framework. I have people (Pajtas class) which are in groups (every group has a unique number). The users can edit the people's information but only if the user has permission to the group in which the person is.
Every user has an IfiAdatlap object and the IfiAdatlap object has the permissions for the numbered groups. So I have a simple permisison class:
public class CsoportHozzaferes
{
[Required]
[Key]
[Column(Order = 1)]
public int Csoport { get; set; }
[Required]
[Key]
[Column(Order = 2)]
public virtual IfiAdatlap IfiAdatlap { get; set; }
}
In my controller I have a function to check that the current user's IfiAdatlap object has permission to the group in which the person is whose information the user would like to edit. First of all I get the current user's ApplicationUser object (user), than I try to get the list of groups (csoportok) for which the user has permission to be able to check that the person's group number (pajtas.Csoport) is in this list or not.
private void PajtasHozzaferesCheck(Pajtas pajtas)
{
var userName = User.Identity.Name;
var user = db.Users.FirstOrDefault(x => x.UserName == userName);
var csoportok = db.CsoportHozzaferesek.Where(h => h.IfiAdatlap != null && h.IfiAdatlap == user.Adatlap).Select(csh => csh.Csoport).ToList();
if (!(pajtas.Csoport != null && csoportok.Contains((int)pajtas.Csoport)))
{
var tanfolyamok = db.TanfolyamHozzaferesek.Where(h => h.IfiAdatlap != null && h.IfiAdatlap == user.Adatlap).Select(tfh => tfh.Tanfolyam).ToList();
var tfosztalyok = db.TanfolyamHozzaferesek.Where(h => h.IfiAdatlap != null && h.IfiAdatlap == user.Adatlap).Select(tfh => tfh.Osztaly).ToList();
if (!(pajtas.TanfolyamOsztaly != null && pajtas.TanfolyamSorszam != null && tanfolyamok.Contains((int)pajtas.TanfolyamSorszam) && tfosztalyok.Contains((TanfolyamOsztaly)pajtas.TanfolyamOsztaly) && tanfolyamok.IndexOf((int)pajtas.TanfolyamSorszam) == tfosztalyok.IndexOf((TanfolyamOsztaly)pajtas.TanfolyamOsztaly)))
{
var tanfvez = db.TanfolyamvezetesHozzaferesek.Where(h => h.IfiAdatlap != null && h.IfiAdatlap == user.Adatlap).Select(tfvh => tfvh.Tanfolyam).ToList();
if (!(pajtas.TanfolyamSorszam != null && tanfvez.Contains((int)pajtas.TanfolyamSorszam)))
{
if (!(User.IsInRole("Nevelo") || User.IsInRole("Admin")))
{
//nincs jogosultság
throw new HttpException((int)System.Net.HttpStatusCode.Forbidden, "Hozzáférés megtagadva");
}
}
}
}
}
But I get an exception at line var csoportok = ...:
System.NotSupportedException: 'Unable to create a constant value of type 'Ifi.Models.Adatlap'. Only primitive types or enumeration types are supported in this context.'
Thanks for any help!
I presume Adaplap is an entity.Change where condition using id instead comparing instances,eg:
.Where(h => h.IfiAdatlap != null && h.IfiAdatlap.Id == user.Adatlap.Id)
The problem is h.IfiAdatlap == user.Adatlap. Because this is a complex type, it won't be accepted, as EF does not know how to do the comparison. You need to compare the ids, something like h.IfiAdatlap.Id == user.Adatlap.Id.

Remove a list of objects and add new ones efficiently using Entity Framework

I'm taking into two multiselect lists into my Edit Action Post method along with a viewmodel. For each multiselect I want to loop through each object and remove what is not selected and add what is.
In this case, I'm adding and removing users from the project that are of a certain role type. Initially I was thinking db.SaveChages() on each iteration but that seems inefficient? Any suggestions for a better approach? Currently this doesn't work... Pardon if I'm way off base, this is my 4th week learning MVC. Thanks in advance!
// POST: Projects/Edit
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Administrator")]
public ActionResult Edit(ProjectEditViewModel vm, int ProjectStatusId)
{
if (ModelState.IsValid)
{
var project = db.Project.Find(vm.ProjectId);
project.Name = vm.ProjectName;
project.ProjectStatusId = ProjectStatusId;
var users = db.Users.Where((u => u.Projects.Any(ui => ui.ProjectId == vm.ProjectId)));
var currentDevs = users.Where(u => u.Roles.Any(ur => ur.RoleId == db.Roles.FirstOrDefault(r => r.Name == "Developer").Id));
var currentPMs = users.Where(u => u.Roles.Any(ur => ur.RoleId == db.Roles.FirstOrDefault(r => r.Name == "Project_Manager").Id));
if (currentDevs != null)
{
foreach (var cd in currentDevs)
{
project.Users.Remove(cd);
}
}
if (currentPMs != null)
{
foreach (var cpm in currentPMs)
{
project.Users.Remove(cpm);
}
}
if (vm.SelectedDevs != null)
{
foreach (var dev in vm.SelectedDevs)
{
var developer = users.FirstOrDefault(a => a.DisplayName == dev);
project.Users.Add(developer);
}
}
if (vm.SelectedPMs != null)
{
foreach (var pm in vm.SelectedPMs)
{
var projMgr = users.FirstOrDefault(a => a.DisplayName == pm);
project.Users.Add(projMgr);
}
}
db.Entry(project).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Details", new { id = vm.ProjectId });
}
return View(vm);
}
Thought I'd swing back around and post my solution for 1 of the two role types. Same logic was applied to the other (1st solution to SO woot!!!)
var devRoleId = db.Roles.FirstOrDefault(r => r.Name == "Developer").Id;
var users = db.Users.ToList();
//currently assigned developers
var currentDevs = (from p in project.Users
where p.Roles.Any(r => r.RoleId == devRoleId)
select p).ToList();
// if the new list is null and old list is not null, remove the old list members
if (vm.SelectedDevs == null)
{
if(currentDevs != null)
{
foreach (var d in currentDevs)
{
project.Users.Remove(d);
}
}
}
//if the new list is not null
if (vm.SelectedDevs != null)
{
if (currentDevs == null) //if the old list is null, add the new list members
{
foreach(var nd in vm.SelectedDevs)
{
project.Users.Add(users.FirstOrDefault( u => u.DisplayName == nd));
}
}
else //if the old list is not null, compare each new list member to old and if its new list member is truely new, add them
{
foreach(var nd in vm.SelectedDevs)
{
if(!currentDevs.Any(cd => cd.DisplayName == nd))
project.Users.Add(users.FirstOrDefault( u => u.DisplayName == nd));
}
}
}
This should work for you. You don't want to remove all the users and re-add them each time. That's going to cause a lot of problems. Instead, you remove only the ones that have been de-selected, and then add only the ones that have been newly-selected (did not exist in the list before).
var devRoleId = db.Roles.FirstOrDefault(r => r.Name == "Developer").Id;
var pmRoleId = db.Roles.FirstOrDefault(r => r.Name == "Project_Manager").Id;
// Remove de-selected devs
project.Users.Where(u => u.RoleId == devRoleId && !vm.SelectedDevs.Contains(u.DisplayName))
.ToList().ForEach(u => project.Users.Remove(u));
// Add newly selected devs
var existingDevs = project.Users.Where(u => u.RoleId == devRoleId).Select(m => m.DisplayName);
db.Users.Where(u => vm.SelectedDevs.Exclude(existingDevs).Contains(u.DisplayName))
.ToList().ForEach(u => project.Users.Add(u));
// Remove de-selected PMs
project.Users.Where(u => u.RoleId == pmRoleId && !vm.SelectedPMs.Contains(u.DisplayName))
.ToList().ForEach(u => project.Users.Remove(u));
// Add newly selected PMs
var existingPMs = project.Users.Where(u => u.RoleId == pmRoleId).Select(m => m.DisplayName);
db.Users.Where(u => vm.SelectedPMs.Exclude(existingPMs).Contains(u.DisplayName))
.ToList().ForEach(u => project.Users.Add(u));

Linq - using multiple variables in a query

I have the following function: -
public IEnumerable<Employee> getEmployees(string department, string searchterm)
{
IEnumerable<Employee> query;
if (department == null || department == ""){
query = from e in db.Employees where e.Date_Leave == null orderby e.EmpSurname select e;
}else{
query = from e in db.Employees where (e.Date_Leave == null) && (e.EmpDept==department) orderby e.EmpSurname select e;
}
return query;
}
At the moment it's just looks at the 'department' variable to determine which query to run but I also want it to look at the 'searchTerm' variable which I will use against the 'EmpSurname' column
My question is, is it possible to have just one query that will use 'department' and 'searchTerm' if they are not null and disregard them if they are null. It could also be that one is null and the other is not.
Thank you
You can compose your query in multiple steps, and it will not be executed until results are actually requested:
public IEnumerable<Employee> getEmployees(string department, string searchterm)
{
IQueryable<Employee> query = db.Employees.Where(e => e.Data_Leave == null);
if (department != null && department != "") {
query = query.Where(e => e.EmpDept == department);
}
if(searchterm != null && searchterm != "") {
query = query.Where(e => e.EmpSurname == searchterm);
}
return query.OrderBy(e => e.EmpSurname);
}
You can use:
var query = from e in db.Employees
where e.Date_Leave == null &&
(department == null || e.EmpDept == department) &&
(searchTerm == null || /* something using searchTerm */)
orderby e.EmpSurname
select e;
Or just conditionally add the queries as Marcin showed. Either approach should be fine.

Conditional RedirectToAction in Controller?

I'm just wondering where, in MVC, the responsibility for determining where to redirect belongs. I think it's the controller, but I'm not sure.
In the Create action of a WorkshopItem I'm creating a new WorkshopItem from the ViewModel passed in, then saving it to the database. Part of the ViewModel is a SelectedCustomerId and CustomerName, if the SelectedCustomerId is empty and the name is empty I get the default customer entity and associate it with the item. If the Id is empty but the name is not then the user has searched for a customer but no matches were found, so I take the value and create a new customer record and attach it.
[NHibernateActionFilter]
[HttpPost]
public ActionResult Create(WorkshopItemCreateViewModel model)
{
try
{
Customer customer = null;
if (model.SelectedCustomerId == new Guid() &&
!string.IsNullOrWhiteSpace(model.CustomerName))
customer = CreateNewCustomer(model.CustomerName);
else if (model.SelectedCustomerId == new Guid() &&
string.IsNullOrWhiteSpace(model.CustomerName))
{
// Assign the System Valued customer if no customer was selected.
var id = Guid.Parse(ConfigurationManager.AppSettings["ValuedCustomerId"]);
customer = Session.QueryOver<Customer>()
.Where(c => c.Id == id)
.SingleOrDefault();
}
// other stuff
return RedirectToAction("Index");
This is working fine, but now I want to also RedirectToAction depending on whether a customer record was created or not because if a customer was created it only has a Name and I'd like to redirect to the Edit action on the Customer Controller passing the CustomerId (which I think I can do). My question is really whether this is valid to do in MVC or should this be a responsibility elsewhere?
This would look like this:
[NHibernateActionFilter]
[HttpPost]
public ActionResult Create(WorkshopItemCreateViewModel model)
{
try
{
Customer customer = null;
bool newCustomer = false;
if (model.SelectedCustomerId == new Guid() &&
!string.IsNullOrWhiteSpace(model.CustomerName))
{
customer = CreateNewCustomer(model.CustomerName);
newCustomer = true;
}
else if (model.SelectedCustomerId == new Guid() &&
string.IsNullOrWhiteSpace(model.CustomerName))
{
// Assign the System Valued customer if no customer was selected.
var id = Guid.Parse(ConfigurationManager.AppSettings["ValuedCustomerId"]);
customer = Session.QueryOver<Customer>()
.Where(c => c.Id == id)
.SingleOrDefault();
}
// other stuff
if (newCustomer)
return RedirectToAction("Edit", "Customer", new {id=customer.Id});
else
return RedirectToAction("Index");
Absolutely, the controller maintains responsibility of returning content and redirecting to the appropriate actions. You can think of the controller as almost a traffic cop, directing things where to go and sending the right stuff to the appropriate places. An example from your code above might look something like this:
if (model.SelectedCustomerId == new Guid() && !string.IsNullOrWhiteSpace(model.CustomerName))
customer = CreateNewCustomer(model.CustomerName);
return RedirectToAction("Edit", new {id = customer.Id});
else if (model.SelectedCustomerId == new Guid() && string.IsNullOrWhiteSpace(model.CustomerName)){
// Assign the System Valued customer if no customer was selected.
var id = Guid.Parse(ConfigurationManager.AppSettings["ValuedCustomerId"]);
customer = Session.QueryOver<Customer>().Where(c => c.Id == id).SingleOrDefault();
return RedirectToAction("SomeOtherMethod");
}
// other stuff
return RedirectToAction("Index");

Resources