How do I get current user another property asp mvc 5 - c#

I have a situation.
AspNetUsers has a column called AccType which is int type
If AccType is 1 = customer
If AccType is 2 = manager.
I can access to current logged user id by User.Identity.GetUserId()
I am trying to do if statment as following:
if(User.Identity.GetUserId().AccType == 1){
redirect to specific page..
}elseif (User.Identity.GetUSerId().AccType == 2){
redirect to 2nd specific page..
}
User.Identity.GetUserId().AccType this is now working.
Please help! Thanks!

User.Identity.GetUserId() returns the id of the currently logged in user. However, if you want to access its properties, you need to get the actual user object. One way to to this is the following:
var userId = this.User.Identity.GetUserId();
var user = this.Request.GetOwinContext().GetUserManager<ApplicationUserManager>().FindById(userId);
A more convenient way will be to make a property for the ApplicationUser in your controller and then to reuse the code.
Property:
public ApplicationUserManager UserManager
{
get
{
return this.Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
}
Getting the user:
var user = this.UserManager
.FindById(this.User.Identity.GetUserId());

Related

Getting Current User in Controller

Hope somebody can help me with this. I am trying to create a Change Password Post Request in the Account controller, but my user is always returning null. I'm new to .NET, could someone help up me figure out the best way to retrive the current user Id? Here is the code I have thus far.
[HttpPost("changePassword")]
public async Task<ActionResult<ChangePasswordDTO>> ChangePassword([FromBody] ChangePasswordDTO changePassword) {
var currentUserId = User.Claims.ToList()
.FirstOrDefault(x => x.Type == "").Value;
var user = await _userManager.FindByIdAsync(currentUserId);
var result = await _userManager.ChangePasswordAsync(user, changePassword.Password, changePassword.NewPassword);
if (result.Succeeded) {
return Ok("Password changed succesfully");
} else return Unauthorized("An error occurred while attempting to change password");
}
When I change the "currentUserId" to a hard coded value, everything works fine, of course. Every user has a generated jwt token with his name, id, roles etc. I'm unsure how to proceed, everything I've tried retrieves the user as null. Let me know if you need extra information, I'm pretty new to all of this and appreciate whatever help I can get, thanks!
Solution
JamesS pointed me in the right direction, this code works:
var currentUserId =this.User.FindFirstValue(ClaimTypes.NameIdentifier);
You can get the current user id in your controller using the UserManager such as:
ASP.NET CORE >= 2.0
var currentUserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
or Name using:
var currentUserId = User.FindFirstValue(ClaimTypes.Name);
If you want to get the current user in some other class, you can use the IHttpContextAccessor, passing it into the class's constructor and using the HttpContext to access the User

RedirectToAction redirecting to wrong User ID

Edit: I am still encountering this issue but I have solved it displaying the applications on 2 users profile instead of the user that created it. I am still running into the issue of redirecting to the wrong ID however and I can't find any information online about it. All the breakpoints up to the redirect point to the correct ID so I am really perplexed. As stated below, I had altered my viewbag and variables to be consistent and it did not fix the issue.
I have an application that allows users to add applications to their profile. Their profile will list all of the applications made by that user. The application has been configured in the RouteConfig file to initialise the application in the profile of UserId 1.
What is happening is that if I create an application for UserId 1, it works fine, adds the application to the list of applications for UserId 1 and displays it. If I create a new user (UserId 2) and then proceed to add a new application for that user, the redirect action that happens when the application is submitted to the database takes me back to UserId 1's page with the application being added to UserId 1's list and also to the UserId that created it (In this instance, UserId 2). I'm not sure why this is happening as I am explicitly telling it to get the UserId from the ViewBag that is storing the correct UserId.
If I look into the database, there is only 1 record for the application. I can delete the application in UserId 1's list and it will still exist in UserId 2's list and also the database. If I remove it through the UserId 2's page, it will remove the record from all lists and database. This also applies to updating the details of the application.
When I've set a breakpoint at the very end where the controller will pick up the UserId and then redirect me to that UserId's page. It states the correct UserId's page it needs to redirect to (In the scenario above, it states the UserId is 2). However, as already stated, it is redirecting me to the UserId 1.
If I remove the route in the RouteConfig file that initialises the application in UserId 1 and just load up the default index page, create a user then create an application, I am given an error stating System.NullReferenceException because I'm trying to display the name of the user using - <h2>User Profile for #Model.Name</h2> so it's not picking up the details of the UserId. I'm not sure why this is happening either as I thought the RouteConfig file was purely to tell the application where to inialise.
Code below, some points to make:
This is what the URL looks like when I am about to submit the application = https://localhost:44313/Service/AddApplication?Course=Level1&DriverId=1&UserId=2
RoutesConfig is sending to "GetUser", "User", 1 at application start
The viewbags are working as I can see that it picks up the correct UserId at the very end of the adding process.
Controller Action to Add Application;
[HttpPost]
public ActionResult AddNewApplication(ApplicationAdd applicationAdd, string UserId, int DriverId)
{
try
{
// TODO: Add insert logic here
applicationService.AddApplication(applicationAdd, UserId, DriverId);
return RedirectToAction("GetUser", "User", new { UserId = ViewBag.UserId });
}
catch
{
return View();
}
}
GetUser action in User Controller:
public ActionResult GetUser(string id)
{
return View(userService.GetUser(id));
}
GetUser action in userService:
public User GetUser(string id)
{
using (var context = new MyContext())
{
return userDAO.GetUser(id, context);
}
}
GetUser in userDAO:
public User GetUser(string id, MyContext context)
{
context.Users.Include(g => g.Applications).ToList();
return context.Users.Find(id);
}
RouteConfig file path:
defaults: new { controller = "User", action = "GetUser", id = 1 }
Controller Action that is giving the view to display the list of applications for a user:
public ActionResult GetApplications(string id)
{
User user = userService.GetUser(id);
IList<Application> applications = user.Applications.ToList();
return View(applications);
}
Try using this
RedirectToAction("GetUser", "User", new { id = ViewBag.UserId });
the parameter name UserId needs to be the same as the one in the funcation id.

C# .NET core Best way to get current user ID

I have a lot of tables in my database that use a user's identity User.Id as a foreign key. Now, in a lot of the requests I need to do the below lines it seems just in case the User is null (even if I add [Authorise] filter to the function).
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
ViewBag.ErrorCode = "1201";
ViewBag.ErrorMsg = "User not found";
return View("HandledError");
}
var userId = user.Id;
Does anyone know the best way I can access this without copying this same code for each function?
I guess I could have a function that retrieves the Id... and throws an exception on Null.. but then I would still need to write it in a try catch everytime anyway....
Any ideas?
User id is a claim. You can get it via:
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
Note: You'll need to add a using for System.Security.Claims.
In WebApi 2 you can use RequestContext.Principal from within a method on ApiController
string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();

How to find the data related to a specific user in ASP.NET MVC

I am now learning ASP.NET MVC 5 and working on a little project to improve my knowledge.
Using Entity Framework, I didn't see until now a table for the Users although there is a login and register functionality.
I wonder for example: what shall I do when I want show the data related to a specific user? With a code like that:
public ActionResult MyAnnoncement()
{
if (!User.Identity.IsAuthenticated)
{
return View("~/Views/Account/Login.cshtml");
}
else
{
return View(db.Voitures.ToList());
}
}
You can use User.Identity.GetUserId() to get the ID of the user from the AspNetUsers table, then populate the User object like this:
ApplicationDbContext db = new ApplicationDbContext();
string uid = User.Identity.GetUserId();
ApplicationUser u = db.Users.Find(uid);
Please note you'll need to add "using Microsoft.AspNet.Identity;" at the top of your code to use User.Identity.GetUserId().
You need an instance of the UserManager "ApplicationUser can be different in your case can by some other object
Then you can do something like this
var user = UserManager.FindById(User.Identity.GetUserId());
the user object has your data

How to delete users that were created with UserManager.CreateAsync

Using asp.net mvc5, my user management systems seems to work. I can login with google or with name/password..
but now I am working on a user management interface in which I need to be able to delete existing users. And this is starting to expose to me just how confusing the user management system is. There's so many different ways to deal with users.. and some of them don't work.
Most everywhere I read, it is talking about using the Membership.DeleteUser().
But that isn't working...
The users were created with.
var user = new ApplicationUser()
{
UserName = model.UserName,
Email = model.Email,
ConfirmationToken = confirmationToken,
IsConfirmed = false
};
var result = await UserManager.CreateAsync(user, model.Password);
Now later on.. how do I delete such a user? (given its name or userid)
I have tried what comes up most on various searches.. comes up with Membership as the solution. But this surely isn't right for MVC5?
For example
var allusers = Membership.GetAllUsers(); // allusers is empty
bool success = Membership.DeleteUser(model.name); // <-- success = false
I can get all the users using this method..
ApplicationDbContext db = new ApplicationDbContext();
foreach (var user in db.Users) { ... }
And I can find an individual user with..
ApplicationDbContext db = new ApplicationDbContext();
var um = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
ApplicationUser user = um.FindById(model.userId);
Now how do I delete one though? ....
Update
As of Microsoft.AspNet.Identity Version 2.0.0.0, you can now delete users with Identity using UserManager.Delete(user);.
For Posterity
You are referring to two different things, Identity and Membership. Newer versions of ASP.NET support Identity and Membership with Identity being the default, while older versions support only Membership (out of those two authentication systems).
When you create a user with UserManager.CreateAsync, you are doing so within the Microsoft.AspNet.Identity namespace. When you are attempting to delete a user with Membership.DeleteUser, you are doing so within the System.Web.Security namespace. They are living in two different worlds.
As another comment mentions, deleting users is not yet supported out of the box by Identity, but it is the first item on their roadmap for a Spring of 2014 release.
But why wait? Add another property to the ApplicationUser model like this:
public class ApplicationUser : IdentityUser
{
public string IsActive { get; set; }
}
Then, in your controller for deleting a user:
user.IsActive = false;
Do a check when the user logs in:
if (user.IsActive == false)
{
ModelState.AddModelError(String.Empty, "That user has been deleted.");
return View(model);
}
When an deleted user attempts to re-register, instead of UserManager.Create, use UserManager.Update with their new information on the registration page.
These steps will effectively delete the user. If you truly must clear their information from your database, you can use Entity Framework to do that more directly.
added to the previous response. If you have
public class ApplicationUser : IdentityUser
{
public string IsActive { get; set; }
}
Then, in your controller for deleting a user:
user.IsActive = false.ToString();
because your data type is a string and n ot a boolean

Categories

Resources