How to get the user logged in - asp.net-mvc

I'm having an issue with trying to set the value to the user that logged in to the website. This is what I have so far but I'm getting this error
Error CS0200 Property or indexer 'Employee.getName' cannot be assigned to -- it is read only. What changes would I make to set the user that logged in the view
Employee Model
public class Employee
{
[Required]
[Display(Name="Employee Number")]
public int employeeNum { get; set; }
[Display(Name = "Employee First Name")]
public string firstName { get; set; }
[Display(Name = "Employee Last Name")]
public string lastName { get; set; }
[Display(Name = "Employee Department")]
public string department { get; set; }
[Display(Name = "Employee Name")]
public string Name
{
get
{
return string.Concat(firstName, " ", lastName);
}
}
public string getName
{
get {
IssueDAO dbObj = new IssueDAO();
dbObj.connectionString = "Server=tw-testdb-04;Database=TWCL_OPERATIONS;uid=sa;password=P#ssw0rd";
var emp= dbObj.getEmployee(employeeNum);
return emp;
}
}
}
}
Controller
private Requisition getRequisition
{
get
{
Requisition requisition = (Requisition)Session["Requisition"];
if (requisition == null)
{
requisition = new Requisition();
Session["Requisition"] = requisition;
}
return requisition;
}
}
public ActionResult RequisitionItem()
{
//Session.Clear();
//Set the document number and type to autoamtic values
IssueDAO dbData = new IssueDAO();
getRequisition.reqDate= DateTime.Now;
getRequisition.reqNumber= string.Concat("RN", DateTime.Now.ToString("yyyyMMddhhmmssms"));
getRequisition.count = 0;
getRequisition.inventory_account = 5520;
getRequisition.employeeDetails.getName = System.Web.HttpContext.Current.User.Identity.Name;
getRequisition.item = new Item();
return View(getRequisition);
}

Property or indexer 'Employee.getName' cannot be assigned to -- it is
read only.
The error is self explanatory. In your Employee class, you have defined getName with only get accessor method for this property. That means, the value of it can only read by some other code. You are trying to set the value to this property and hence the compiler is complaining about it.
If you want the value of this property to be settable by some other code, you should have a set access modifier on this property.
IMHO, you should keep your view models lean and simple. There should not be any data access code to get data inside a view model properties ( that is mixing 2 concerns ,UI and Data access together!)
I suggest you have a settable and gettable property in your view model to pass the logged in user name
public class Employee
{
// Your other properties
public string LoggedInUserName { set;get;}
}
Now you can set this as needed
var emp=new Employee();
emp.LoggedInUserName = "Any username value here";
or
emp.LoggedInUserName = System.Web.HttpContext.Current.User.Identity.Name;

Related

Model - field based on values in other fields

I've literally just started learning MVC.
I have created a simple model:
public class StaffMember
{
public Guid StaffMemberId { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Team { get; set; }
public virtual ICollection<Observation> Observations { get; set; }
}
Now I have decided that I want to include a drop down list of all StaffMembers on the create page for the observation records. I manage to do that with the following code:
#Html.DropDownListFor(o => o.StaffMemberId,
new SelectList(Model.StaffMembers,
"StaffMemberId",
"Forename",
Model.StaffMemberId),
"-- Select Staff Member --")
This works perfectly, although, you'll notice that I can only include a single field, "Forename".
I want the drop down list to show the staff member's full name. I tried concatenating the fields manually i.e. "Forename" + " " + "Surname" but that threw and exception about there being no such field as "Forename" + " " + "Surname".
My question is this - is it possible to add to my model some sort of property that is simply based on the value of two existing properties. Something like:
public class StaffMember
{
private string _fullName;
public Guid StaffMemberId { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Team { get; set; }
public virtual ICollection<Observation> Observations { get; set; }
public string FullName
{
get
{
return _fullName;
}
set
{
value = this.Forename + " " + this.Surname;
_fullName = value;
}
}
}
I tried the above, but when populating my database (I'm using entity model code first), that field always has a value of null, even though the field shows the correct value when debugging.
I'm using the following to auto populate the db with some test data:
var staff = new List<StaffMember>
{
new StaffMember
{
Forename = "Bob",
Surname = "Hope",
StaffMemberId = Guid.NewGuid(),
Team = "Test"
},
new StaffMember
{
Forename = "Stan",
Surname = "Laurel",
StaffMemberId = Guid.NewGuid(),
Team = "Test"
}
};
staff.ForEach(s => context.StaffMembers.Add(s));
context.SaveChanges();
Any pointers would be really useful here, especially if I am approaching this in completely the wrong way!
Yes, you're really close with the FullName property.
public class StaffMember
{
public string FullName
{
get
{
return this.Forename + " " + this.Surname;
}
}
}
No need for a private _fullName since you only need to get the values of Forename and Surname. And you don't need a set since you won't set a value back to this model using FullName
You can make this change in your Repository where you add Staff_Member
public void AddStaff(Staff_Member sm)
{
String fullName = sm.Forename.ToString()+" "+sm.Surname.ToString();
sm.FullName = fullName;
_context.Staff_Member.Add(sm);
}
However, you need to have set method for FullName as well in your Staff_Member model.

Securing objects in ViewModel

I am trying to get security settings from the database for objects in a model. I would like to enable / disable / hide controls on my Rendered View depending upon the security settings for a user logged in.
This is what I have got so far:
public class RestrictedObjectsViewModel
{
[SecureObject(ObjectId = 1)]
[Display(Name = "Name")]
public string Name { get; set; }
[SecureObject(ObjectId = 2)]
[Display(Name = "Address")]
public string Address { get; set; }
[SecureObject(ObjectId = 3)]
[Display(Name = "Phone Number")]
public string PhoneNumber { get; set; }
}
Using this approach, I would be querying the database for each object being rendered. Is it possible to query the database just once for the entire objects in the model to get a list of permissions for objects? How would I set that?
UPDATE:
Ok, let me go a bit into detail.
In my code when I set the following attribute to an object, i have programmed my HTML to hide the associated table row for the rendered object:
[SecureObject(IsInvisible = true)]
The above code works correctly in my tests. However, when i try to do the following:
public class RestrictedObjectsViewModel
{
[SecureObject(IsInvisible = ObjectId3Invisible)]
[Display(Name = "Phone Number")]
public string PhoneNumber { get; set; }
public RestrictedObjectsViewModel(bool setPermissions = false)
{
if (setPermissions)
{
ObjectId3Invisible = true;
}
}
public bool ObjectId3Invisible = false;
}
I get an error message saying "An object reference is required for the non-static field, method, or property 'MyProject.Models.RestrictedObjectsViewModel.ObjectId3Invisible'"
Here is the controller:
public ActionResult RestrictedObjects()
{
return View(new Models.RestrictedObjectsViewModel(true));
}
If i change the ObjectId3Invisible to static, i will not be able to change the value to true or false during runtime.
Any suggestions?

How to make an array for timestamps on MVC 3

I am fairly new to MVC 3 and I was tasked with creating a to-do list, that has got timestamps for every independent variable, so when one variable changes, the timestamp of when it was changed would appear on the text field of that variable and not change the other timestamps of the other variables i.e each variable would have an individual timestamp. I believe I can only or most likely achieve this by creating an array. Any ideas on how I can carry this out?
I dummy code would be really appreciated
Here's a sample of my model, I followed this tutorial http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/intro-to-aspnet-mvc-3
public class Checklist
{
public int ID { get; set; }
public string Title { get; set; }
public string Status { get; set; }
[Display(Name = "Start Date")]
public string Start_Date { get; set; }
[Display(Name = "Complesion Date")]
public string Complesion_Date { get; set; }
public DateTime[] Timestamp
{
get { return timestamp; }
set { timestamp = value; }
[Display(Name = "Internal Review System Reference")]
public string Internal_Review_System_Reference { get; set; }
[Display(Name = "Assignment from Original Owner")]
public bool Assignment_from_Original_Owner { get; set; }
public class listDBContext : DbContext
{
public DbSet<Checklist> List { get; set; }
}
And here's a sample of my controller code
public class SybreController : Controller
{
private listDBContext db = new listDBContext();
private Checklist check = new Checklist();
private string oldTitle { get; set; }
private string oldStatus { get; set; }
public ActionResult Edit(int id)// Called when edit button is clicked
{
Checklist checklist = db.List.Find(id);
this.oldTitle = checklist.Title;
this.oldStatus = checklist.Status;
//initAllArrays(checklist);//initialize our arrays with previous values
return View(checklist);
}
[HttpPost]
public ActionResult Edit(Checklist checklist)
{
if (ModelState.IsValid)
{
checklist.Timestamp = DateTime.Now;
if (checklist.Title != this.oldTitle)
{
checklist.stamps[0] = DateTime.Now;
}
if (checklist.Status != this.oldStatus)
{
checklist.stamps[1] = DateTime.Now;
}
else
{ checklist.stamps[1] = checklist.stamps[1]; }
db.Entry(checklist).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
Basically I need an timestamp for every individual variable in my model, so that when edited, the timestamp corresponded to when it was edited, the problem I've been facing is the timestamp variable changes across all the variables instead of only the one which was changed. I just need the program to print the former timestamp from when it was last edited, and if edited, display the current time along side the text field.
Hope you understand -__-
You can't solve your problem in this way. Asp.net MVC is stateless, it means that the instance of the controller is created per every request. It means that the checks that you have performed to set time stamps have always true value, as oldTitle and oldStatus are nulls.

Object reference not set to an instance of an object error MVC3

I have a ajax post which give me the values from what the user have typed into my form.
And in my database I have two entites that are being used and I use model first.
However Im getting "Object reference not set to an instance of an object" error when trying to do this:
goalCardQuestionAnswer.SelectedQuestion.Id = selectedQuestionViewModel.QuestionID;
This is my controller post:
[HttpPost]
public bool AnswerForm(SelectedQuestionViewModel selectedQuestionViewModel)
{
if (ModelState.IsValid)
{
var goalCardQuestionAnswer = new GoalCardQuestionAnswer();
goalCardQuestionAnswer.SelectedQuestion.Id = selectedQuestionViewModel.QuestionID;
goalCardQuestionAnswer.Comment = selectedQuestionViewModel.Comment;
goalCardQuestionAnswer.Grade = selectedQuestionViewModel.Grade;
answerNKIRepository.SaveQuestionAnswer(goalCardQuestionAnswer);
answerNKIRepository.Save();
}
My SelectedQuestionViewModel:
public class SelectedQuestionViewModel
{
public int? Grade { get; set; }
public string Comment { get; set; }
public string SelectedQuestionText { get; set; }
public int QuestionID { get; set; }
}
My database model
You must initialize your SelectedQuestion property:
var goalCardQuestionAnswer = new GoalCardQuestionAnswer();
goalCardQuestionAnswer.SelectedQuestion = new SelectedQuestion();
If I were you I would also add a foreign key property SelectedQuestionId to my model. Then you can set this value and your navigation property will be automatically retrieved upon SaveChanges or when you request the object from your repository.

MVC LINQ to SQL JOIN for custom type fails for a strongly typed view

I have a simple data model of two tables, email and recipients, email can be sent to one or more recipients
I have setup the database with the two tables, created the Linq to SQL repository, built the controllers and the strongly typed view.
This works fine when I want to select all records from the database
public IList<AllMailDetail> ListAll()
{
var allMail =
from m in _datacontext.mail_receiveds
join r in _datacontext.mail_recipients on m.DeliveryId equals r.DeliveryId
select new AllMailDetail {
DeliveryId = m.DeliveryId,
MessageId = m.MessageId,
SentFrom = m.SentFrom,
FilePath = m.FilePath,
FileName = m.FileName,
SentDateTime = m.SentDateTime,
ReceivedDateTime = m.ReceivedDateTime,
Subject = m.Subject,
SpamScore = m.SpamScore,
IsSpam = m.IsSpam,
SenderIP = m.SenderIP,
Header = m.Header,
SentTo = r.SentTo
};
return allMail.ToList <AllMailDetail>();
}
The custom type class
public class AllMailDetail
{
public int DeliveryId { get; set; }
public int? MessageId { get; set; }
public string SentFrom { get; set; }
public string FilePath { get; set; }
public string FileName { get; set; }
public string SentDateTime { get; set; }
public DateTime ReceivedDateTime { get; set; }
public string Subject { get; set; }
public byte? SpamScore { get; set; }
public bool? IsSpam { get; set; }
public string SenderIP { get; set; }
public string Header { get; set; }
public string SentTo { get; set; }
}
The controller simply sends the contents from the repository to the strongly typed view
public ActionResult Index()
{
return View(_repository.ListAll());
}
To get just one mail record from the database I have the following code that accepts a deliveryId
public IQueryable<AllMailDetail> GetMail(int? id)
{
var allMail =
from m in _datacontext.mail_receiveds
join r in _datacontext.mail_recipients
on m.DeliveryId equals r.DeliveryId
where m.DeliveryId == id
select new AllMailDetail
{
DeliveryId = m.DeliveryId,
MessageId = m.MessageId,
SentFrom = m.SentFrom,
FilePath = m.FilePath,
FileName = m.FileName,
SentDateTime = m.SentDateTime,
ReceivedDateTime = m.ReceivedDateTime,
Subject = m.Subject,
SpamScore = m.SpamScore,
IsSpam = m.IsSpam,
SenderIP = m.SenderIP,
Header = m.Header,
SentTo = r.SentTo
};
return allMail;
}
And its controller code
public ActionResult Details(int? id)
{
var mail = _repository.GetMail(id);
if (mail == null)
return View("NotFound");
return View(mail);
}
I had been trying to display the output for a single record by also using a strongly typed view having Inherits="System.Web.Mvc.ViewPage At the top of the aspx page but I got the following error
The model item passed into the dictionary is of type 'System.Data.Linq.DataQuery`1[projectMail.Models.AllMailDetail]' but this dictionary requires a model item of type projectMail.Models.AllMailDetail'.
I fixed this error after much searching and found this post most helpful
MVC LINQ to SQL Table Join Record Display
so my view is no longer strongly typed and I build the page as follows
<% foreach (projectMail.Models.AllMailDetail item in (IEnumerable)ViewData.Model)
{ %>
...items...
<% } %>
This works fine, but it seems the long way round. The thing I can’t figure out is
Why does the second query need to be IQueryable
Why didn’t it work when the view was strongly typed
How can it be made to work with a strongly typed view
Is this the best way of dealing with joins in MVC using LINQ to SQL
Hmmmm, Try in the controller
return View(_repository.GetMail( id).SingleOrDefault());
You're trying to bind an IQueryable datasource to an AllMailDetail View, the above should fix you.

Resources