MVC3 Edit customer with username - asp.net-mvc-3

I am trying to edit customer with username which is using User.Identity.Name.
I don't know how to write Where condition in controller.
It looks easy. Could you help me? thanks.
Here is my coding.
[Authorize]
public ActionResult Edit()
{
//the username gets username through User.Identity.Name.
string username = User.Identity.Name;
//How can I write below coding?
//In DB, it has userName field.
Customer customer = db.Customer.Where(userName = username);
return View(customer);
}
[HttpPost]
public ActionResult Edit(Customer customer)
{
if (ModelState.IsValid)
{
db.Entry(customer).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}

You need to learn how lambda expressions work:
.Where(c => c.UserName == username)
c is the implicitly-typed parameter.
Also, if you want a single result, you should call FirstOrDefault() instead; Where() returns a sequence.

Customer customer = db.Customer.Single(c=>c.UserName == username)
throws exception if returns one than more matching element
or
Customer customer = db.Customer.SingleOrDefault(c=>c.UserName == username);
returns null if returns more than one matching element

Related

Is validating a userId (or any other data extracted from an authentication token) necessary?

In my controller action as have something like this:
[HttpGet]
[ActionName("approve")]
[Authorize(Policy = "Approve")]
public IActionResult GetEntitiesToBeApproved()
{
var stringUserId = User.Claims.FirstOrDefault(c => c.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier")?.Value;
Guid.TryParse(stringUserId, out var userId);
if (userId == default(Guid))
{
return StatusCode((int)HttpStatusCode.BadRequest, ConstantValues.InvalidUserId);
}
//service calls etc.
return Ok();
}
Is there any point in checking that the userId is valid (non-default) or can I skip it?
You can skip it, Authorize filter attribute check it for You.

I Want to execute second Login(contactnumber,password) but after passing the argument it is still calling the list login method How to resolve this?

I Want to execute second Login(contactnumber,password) but after passing the argument it is still calling the list login method How to resolve this?
[HttpGet]
public IEnumerable<UserDetail> Login()
{
using (HeandSheEntities entities = new HeandSheEntities())
{
return entities.UserDetails.ToList();
}
}
[System.Web.Http.AcceptVerbs("GET")]
[System.Web.Http.HttpGet]
public HttpResponseMessage Login(String ContactNumber, String Password) {
{ String Upass = encryption(Password);
using (HeandSheEntities entities = new HeandSheEntities())
{
bool userphone = entities.UserDetails.Any(u => u.UserContactNumber.Equals(ContactNumber));
bool userpass = entities.UserDetails.Any(u => u.UserPassword.Equals(Upass));
if (ModelState.IsValid && userphone && userpass)
{
var user = entities.UserDetails.FirstOrDefault(u => u.UserContactNumber.Equals(ContactNumber));
if (user != null)
return Request.CreateResponse(HttpStatusCode.OK, user, new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
else
return Request.CreateResponse(HttpStatusCode.BadRequest, "Either Contact Number or password is not correct", new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest, "Either Contact Number or password is not correct", new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"));
}
}
}
}
You use the same name for both action methods with the same http verb. You cannot overload action methods. See here and here. Semantically you should use POST http method for changing state (for example logging user) and it will work.
[HttpPost]
public HttpResponseMessage Login(String ContactNumber, String Password)

ASP.net MVC 3 customizing Html.ValidationMessageFor based on model logic

I've been reading over several of the questions similar to this, dealing with customizing the #Html.ValidationMessageFor but none of them touched on what I'm looking to do.
The current form I'm working on is editing a user in a database. Within this form I need to check that the email being entered is not already used for another user. I have the logic, but what I don't have is the custom validation message to appear on the page if they use an already in-use email.
Controller code:
[HttpPost]
public ActionResult EditUser(int id, EditUserModel model)
{
if (ModelState.IsValid)
{
tbl_Users editedUser = tblUsers.EditUser(id, model, HttpContext.User.Identity.Name);
tblHSDA.EditHSDAS(id, editedUser, model.hsdas, HttpContext.User.Identity.Name);
return Redirect("~/UserManage/ListActiveUsers");
}
if (tblUsers.ValidateEmailInUse(model.Email))
{
// change validation message and return View(model);
}
tbl_Users tbl_users = db.tbl_Users.SingleOrDefault(item => item.User_id == id);
ViewBag.hsdas = tblHSDA.GetHSDANameAlpha();
ViewBag.Username = tbl_users.Username;
return View(model);
}
Is this something done at the Controller level?
as per your logic the email check part will never execute if the user fills in the form correctly and provides a duplicate email
what you can do is change the ActionResult like
[HttpPost]
public ActionResult EditUser(int id, EditUserModel model)
{
if (ModelState.IsValid)
{
if(!CheckEmail(model.Email)){
tbl_Users editedUser = tblUsers.EditUser(id, model, HttpContext.User.Identity.Name);
tblHSDA.EditHSDAS(id, editedUser, model.hsdas, HttpContext.User.Identity.Name);
return Redirect("~/UserManage/ListActiveUsers");
}else{
ModelState.AddModelError("Email","Email provided is already in use...")
}
}
tbl_Users tbl_users = db.tbl_Users.SingleOrDefault(item => item.User_id == id);
ViewBag.hsdas = tblHSDA.GetHSDANameAlpha();
ViewBag.Username = tbl_users.Username;
return View(model);
}
private bool CheckEmail(string email){
//email check logic
// return true or false
}
also have a look at http://msdn.microsoft.com/en-us/library/gg508808%28v=vs.98%29.aspx

Values on PostBack getting lost

I am using MVC3 and classes generetad from EntityFranmework for saving some data into a Database.
The controller
// Get
public ActionResult Create(Guid StudentID)
{
Semester semester = new Semester();
ViewBag.BranchID = new SelectList(db.Branches, "ID", "Name");
semester.Student = db.Students.Single(s => s.ID == StudentID);
return PartialView(semester);
}
//
// POST: /Semester/Create
[HttpPost]
public ActionResult Create(Semester semester)
{
semester.ID = Guid.NewGuid();
semester.CreatedDate = DateTime.Now;
semester.CreatedBy = "ddf";
db.Semesters.AddObject(semester);
db.SaveChanges();
return RedirectToAction("Index", "Student");
}
I do get all the result of the student at get Method but all the student data are Lost at the post method.
Help!
The object passed to POST action is not the same as object passed to the view in GET action. In your POST action you get Semester instance created by MVC using only parameters Request (query string, post data) - that means Student instance is long gone. You will need to pass student ID to POST action and fill it there.
[HttpPost]
public ActionResult Create(Guid studentID, Semester semester)
{
semester.ID = Guid.NewGuid();
semester.CreatedDate = DateTime.Now;
semester.CreatedBy = "ddf";
semester.Student = db.Students.Single(s => s.ID == StudentID);
db.Semesters.AddObject(semester);
db.SaveChanges();
return RedirectToAction("Index", "Student");
}

MVC Delete record but how to code this in Controller

I'm a beginner of MVC3 with ASP.Net (C#) but I don't get the next situation to delete a record.
I have a View that ask the user to confirm delete a item (record). As code I have this to initialize the view:
public ActionResult KeywordsDelete(Guid id)
{
_db = new BlaContext();
return _db.SearchTerms.Where(x => x.id.Equals(id)).First();
}
But when confirmed, then I have the next code.
[HttpPost]
public ActionResult KeywordsDelete(Guid id)
{
_db = new BlaContext();
var term = _db.SearchTerms.Where(x => x.id == id).First();
_db.SearchTerms.Remove(term);
_db.SaveChanges();
return View("Keywords", _db.SearchTerms.ToList());
}
Building is not possible because the signature of this method is already exists (same parameters and method name).
So I don't get how to delete a record in this situation. The view is created with a default Scaffold template (delete).
I found an alternative solution to this problem while reading up on MVC. Check out: Improving the Details and Delete Methods
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id = 0)
{
// Delete stuff...
}
This will route the action Delete to the method DeleteConfirmed.
You can give your post function another additional parameter
[HttpPost]
public ActionResult KeywordsDelete(Guid id, FormCollection collection)
{
_db = new BlaContext();
var term = _db.SearchTerms.Where(x => x.id == id).First();
_db.SearchTerms.Remove(term);
_db.SaveChanges();
return View("Keywords", _db.SearchTerms.ToList());
}
But your GET Action should also return a View not a data object, I think.
public ActionResult KeywordsDelete(Guid id)
{
_db = new BlaContext();
return View(_db.SearchTerms.Where(x => x.id.Equals(id)).First());
}

Resources