Unable to cast Session UserID to database - c#

Im trying to get the current user form the session UserId but get this error. 'Unable to cast object of type 'System.Int32' to type 'Trinity.Models.tblUser'.'
Where I createthe Session Id:
[HttpPost]
public ActionResult Authorise(tblUser user)
{
using (var db = new TrinityEntities())
{
var userEmail = db.tblUsers.FirstOrDefault(x => x.Email == user.Email);
var userPassword = db.tblUsers.FirstOrDefault(y => y.Password == user.Password);
//check login incorrect
if (userEmail == null || userPassword == null)
{
ViewBag.LoginIncorrect = "E-mail or Password not correct";
return View("Index", user);
}
else
{
Session["UserID"] = userEmail.Id;
return RedirectToAction("Index", "Home");
}
}
}
Where I get the error:
public ActionResult Index()
{
if (Session["UserID"] == null)
{
return Redirect("/");
}
var currentUser = (Models.tblUser) Session["UserID"];
using (var db = new Models.ChatContext())
{
ViewBag.allUsers = db.Users.Where(u => u.FirstName != currentUser.FirstName).ToList();
}
ViewBag.currentUser = currentUser;
return View();
}

You're only storing the ID (a number) but when you read it back you're expecting the whole user - that's not going to work. Instead you'll need to use the ID to reload the user:
var currentUserId = Session["UserID"];
var user = db.tblUsers.FirstOrDefault(x => x.Id == currentUserId);

Related

How to pass data to other controllers and views?

How can I get the user's userID from Login Controller and pass it to the other controllers and views?
LOGIN CONTROLLER
public ActionResult Index(Table_User user)
{
var user1 = repo.Find(x => x.UserMail== user.UserMail);
if (user1 != null)
{
if (SecurityAlgorithms.CheckMD5Hash(user.UserPassword, user1.UserPassword))
{
FormsAuthentication.SetAuthCookie(user1.UserName, false);
Session["user1"] = user.UserName;
return RedirectToAction("Index", "Home", new { area = "" });
}
else
{
ViewBag.ErrorMessage = "Check your password!";
return View("Index", user);
}
}
You can use Tempdata or use return RedirectToAction("Action", "Controller", new { userID= user.userID });

C# and ASP.NET MVC : how to check if record exist in database and return id

I'm creating an ASP.NET MVC application in C# to collect users into a database.
The initial page will be a form to search if the client already exist in database.
If it does not exist, I will redirect to a subscription page; if it already exists, I need to redirect to detail page to show the information.
The main problem that I have is when I find the client an try to show the detail, I cant get the id associated with the client above an example:
In the database I have:
EmpID
Name
Address
Age
Salary
Worktype
0
Kevin
Boston
23
1000
Dev
I need to match the EmpID == 0 with the Name == Kevin.
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult IndexDetail([Bind(Include = "EmpID,Name")] EmployeeDetails employeeDetails)
{
if (ModelState.IsValid)
{
var userexist = db.EmployeeDetails.Any(x => x.Name == employeeDetails.Name);
if (userexist)
{
return RedirectToAction("Details", "Register", new { id = employeeDetails.EmpID });
}
else
{
return RedirectToAction("Create", "Register", new { id = employeeDetails.EmpID });
}
}
return View(employeeDetails);
}
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
EmployeeDetails employeeDetails = db.EmployeeDetails.Find(id);
if (employeeDetails == null)
{
return HttpNotFound();
}
return View(employeeDetails);
}
If someone can help me in this matter, I am very grateful.
Your error is when referencing the ID of the existing record here:
var userexist = db.EmployeeDetails.Any(x => x.Name == employeeDetails.Name);
if (userexist)
{
return RedirectToAction("Details", "Register", new { id = employeeDetails.EmpID });
}
else
{
return RedirectToAction("Create", "Register", new { id = employeeDetails.EmpID });
}
Referencing employeeDetails.EmpID in this part is faulty, because the ID doesn't exist on your form, or more precise, it reverts do default value. You should get the ID of the record that is already saved in the database:
if (userexist)
{
var emId = db.EmployeeDetails.FirstOrDefault(x => x.Name == employeeDetails.Name).EmpID;
return RedirectToAction("Details", "Register", new { id = emID });
}

Allow User to see only their own post C# ASP.NET CORE MVC

I am trying to create restrictions in my WebApp. I want to create that every registered and logged-in User can see only their own post and can not see, edit or delete other posts.
So far I try to follow some posts here but this post doesn't give me more information.
Solution 1
So only if the user is Register their should be able to see their own posts not another post from other users.
Anyone, how can tell me and guide me what Do I need to do?
P.S: I also look and the [Authorize] attribute is not the solution which I am looking.
Here is my code:
public IActionResult Upsert(int? Id)
{
TicketVM ticketVM = new TicketVM()
{
Ticket = new Ticket(),
TicketTypeList = _unitOfwork.TicketType.GetAll().Select(i => new SelectListItem
{
Text = i.Name,
Value = i.Id.ToString()
}),
ApplicationUser = new ApplicationUser(),
Client = new Client()
};
if (Id == null)
{
return View(ticketVM);
}
ticketVM.Ticket = _unitOfwork.Ticket.Get(Id.GetValueOrDefault());
if (ticketVM.Ticket == null)
{
NotFound();
}
return View(ticketVM);
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upsert(TicketVM ticketVM)
{
var userName = User.FindFirstValue(ClaimTypes.Email);
var user = HttpContext.User.Identity.Name;
if (ModelState.IsValid)
{
if (ticketVM.Ticket.Id == 0)
{
ticketVM.Ticket.ApplicationUser = _db.ApplicationUsers.FirstOrDefault(u => u.Email == userName);
ticketVM.Ticket.Status = TicketStatus.Otvoren.ToString();
_unitOfwork.Ticket.Add(ticketVM.Ticket);
}
else
{
_unitOfwork.Ticket.Update(ticketVM.Ticket);
}
_unitOfwork.Save();
return RedirectToAction(nameof(Index));
}
return View(ticketVM);
}
public IActionResult Details(int? Id)
{
TicketVM ticketVM = new TicketVM()
{
Ticket = _unitOfwork.Ticket.Get(Id.GetValueOrDefault())
};
if (Id == null)
{
return NotFound();
}
var ticketType = _unitOfwork.Ticket.GetAll(includeProperties: "TicketType,ApplicationUser");
if (ticketVM.Ticket == null)
{
return NotFound();
}
return View(ticketVM);
}

Return Partial view from different method in same controller

I am trying to return a partial view (modal) from another method but I am unsure of how to get the object from the Edit User model into RemoveUserClaim method. When I delete a claim from a user, I want it to return back to the Edit User Modal, right now - I can only get it to redirect to the home maintenance screen.
[HttpPost]
public async Task<IActionResult> RemoveUserClaim(UserClaimsViewModel model, string userid, string claimtype)
{
var user = await userManager.FindByIdAsync(model.UserId);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {model.UserId} cannot be found";
return View("~/Views/Administration/Users/UserMaint.cshtml");
}
var claims = await userManager.GetClaimsAsync(user);
foreach (var claimtypething in claims)
{
if (claimtypething.Type == claimtype)
{
var results = await userManager.RemoveClaimAsync(user, claimtypething);
break;
}
}
//Right here is where I want to return back to EditUser's modal -----------
return PartialView("~/Views/Modals/_EditUserModalPartial.cshtml");
}
[HttpGet]
public async Task<IActionResult> EditUser(string id)
{
var user = await userManager.FindByIdAsync(id);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {id} cannot be found";
return View("NotFound");
}
var userClaims = await userManager.GetClaimsAsync(user);
var userRoles = await userManager.GetRolesAsync(user);
var model = new EditUserViewModel
{
Id = user.Id,
Email = user.Email,
UserName = user.UserName,
City = user.City,
};
//GET LIST OF ROLES (RoleID, RoleName)
foreach (var RoleName in userRoles)
{
//Execute identiy method to get full information for the Role and store into an object (fullroleinfo)
var fullRoleInfo = await roleManager.FindByNameAsync(RoleName);
//Store this inforamtion into the Role list in the viewmodel
var roleinfo = new EditUserViewModel.Role
{
RoleName = fullRoleInfo.Name,
RoleID = fullRoleInfo.Id
};
model.Roles.Add(roleinfo);
};
//GET LIST OF CLAIMS
foreach (var ClaimName in userClaims)
{
var fullClaimInfo = ClaimName;
var claiminfo = new EditUserViewModel.Claim
{
ClaimType = fullClaimInfo.Type,
ClaimID = fullClaimInfo.Value
};
ViewBag.ClaimType = fullClaimInfo.Type;
model.Claims.Add(claiminfo);
};
ViewBag.UserModel = model;
return PartialView("~/Views/Modals/_EditUserModalPartial.cshtml", model);
}

MVC.Net Custom registration/login error "The salt was not in an expected format of {int}.{string}"

I need your help. I'm trying to make a custom registration/login in MVC.Net, which uses SimpleCripto to encrypt the passwords. After I register a user everything is saved in my table and it seems all right, but when I try to LogIn I get an error - "The salt was not in an expected format of {int}.{string}", which comes from my "IsValid" method, in the statement "if (user.Password == crypto.Compute(user.PasswordSalt, password))". I'll post my AuthenticantionController with the Register and LogIn methods and if you can point where the problem is and how to solve it I'll be grateful. Thanks in advance !
namespace Final.Controllers
{
public class AuthenticationController : Controller
{
[HttpGet]
public ActionResult LogIn()
{
return View();
}
[HttpPost]
public ActionResult LogIn(Models.User user)
{
if (IsValid(user.Email, user.Password))
{
FormsAuthentication.SetAuthCookie(user.Email, false);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "Login details are wrong.");
}
return View(user);
}
[HttpGet]
public ActionResult Register()
{
return View();
}
[HttpPost]
public ActionResult Register(Models.User user)
{
try
{
if (ModelState.IsValid)
{
using (AppContext db = new AppContext())
{
var crypto = new SimpleCrypto.PBKDF2();
var encrypPass = crypto.Compute(user.Password);
var newUser = db.Users.Create();
newUser.FirstName = user.FirstName;
newUser.LastName = user.LastName;
newUser.Email = user.Email;
newUser.CompanyName = user.CompanyName;
newUser.Password = encrypPass;
newUser.PasswordSalt = crypto.Salt;
newUser.AdminCode = 0;
user.Password = encrypPass;
user.PasswordSalt = crypto.Salt;
db.Users.Add(newUser);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "Data is not correct");
}
}
catch (DbEntityValidationException e)
{
foreach (var validationErrors in e.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation(
"Class: {0}, Property: {1}, Error: {2}",
validationErrors.Entry.Entity.GetType().FullName,
validationError.PropertyName,
validationError.ErrorMessage);
}
}
}
return View();
}
private bool IsValid(string email, string password)
{
var crypto = new SimpleCrypto.PBKDF2();
bool IsValid = false;
using (AppContext db = new AppContext())
{
var user = db.Users.FirstOrDefault(u => u.Email == email);
if (user != null)
{
if (user.Password == crypto.Compute(user.PasswordSalt, password))
{
IsValid = true;
}
}
}
return IsValid;
}
public ActionResult LogOut()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index", "Home");
}
}
}
Please check the crypto.Compute function parameters. It requires textToHash(which is your password) and salt. You have to interchange the parameters.
you need to modify your IsValid function like this:
private bool IsValid(string email, string password)
{
var crypto = new SimpleCrypto.PBKDF2();
bool IsValid = false;
using (AppContext db = new AppContext())
{
var user = db.Users.FirstOrDefault(u => u.Email == email);
if (user != null)
{
if (user.Password == crypto.Compute(password, user.PasswordSalt))
{
IsValid = true;
}
}
}
return IsValid;
}

Categories