I'm using C#, ASP.NET MVC and .NET 4.5. I have a test controller which only I can access, basically I want to be able to create test users of say 500 at a time and insert these into my aspnetusers table, this is on my test environment.
In my controller I have this:
RegisterViewModel model = new RegisterViewModel();
var s = Guid.NewGuid().ToString();
model.AccountType = accountType;
model.Email = s + "#email.com";
model.Password = s;
model.ConfirmPassword = s;
var result = new AccountController().Register(model);
This goes off to the standard register controller:
public async Task<ActionResult> Register(RegisterViewModel model)
However, it won't register a user? It goes wrong at the CreateAsync part:
var user = new ApplicationUser { UserName = model.Email, Email = model.Email, AccountType = model.AccountType };
var result = await UserManager.CreateAsync(user, model.Password);
I have seen others mention about "seeding" this at the start but I don't want to do this, I've have loads of data I need to automate/add in once the user is in the system, so need to loop over each user entered then insert a load more data. I don't want to have to create an account for each manually and then have to add in all the other details in all the other tables also.
Surely there is a simple way to do this that somebody knows?..
make your non-sync function like that...
public class TestController : Controller
{
ApplicationDbContext db = new ApplicationDbContext();
// GET: Test
public ActionResult Index()
{
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
string s = "User!1Nom"; // must contain special char if you use asp.net identity default validation
for (int i = 1; i < 501; i++)
{
s = s + i;
var user = new ApplicationUser { UserName = s, Email = s+"#gmail.com" };
var result = userManager.Create(user, s);
}
return View();
}
}
Related
I need to create a controller that will get and delete all users and a certain user, respectively and I've figured out the part to get the users, add them to a list and return the list. But I struggle with the get roles part. Initially I tried a Linq Select and that works just fine (and looks decent) for simply getting the roles but doesn't work for getting the roles for that specific user as well. I've also tried a much worse methods: getting all the users from db in a list, foreach the list and for every iteration in the foreach, create a new object of the type I want to return and assign the role for that user to the respective object property. Doesn't work AND it's ugly.
TL;DR : is this the proper way to get roles in a select and does the 'Role' property need to be IList 100%?
Here's my GetRoles method:
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult GetUsers()
{
var userDbList = _userManager.Users.ToList();
if (userDbList is null) return BadRequest(AppResources.UsersDoNotExist);
// my initial select. GetUsersModel is just a model for the object
// I return and contains Name, Email, UserName and Role. As you can see,
// the method is async but I get a cannot implicitly convert System.Collections
// .Generic.IList<string> to string (I suspect I need to set Role as a List<string>?)
var userList = userDbList.Select(async user => new GetUsersModel
{
Name = $"{user.FirstName} {user.LastName}",
UserName = user.UserName,
Email = user.Email,
Role = await _userManager.GetRolesAsync(user)
});
/*var userList = new List<GetUsersModel>();
foreach (var user in userDbList)
{
userList.Add(new GetUsersModel
{
Name = $"{user.FirstName} {user.LastName}",
UserName = user.UserName,
Email = user.Email,
Role = await _userManager.GetRolesAsync(user)
});
}*/
return Ok(userList);
}
I have a similar method for deleting a user, only I first check request data and remove the user if everything's ok and then create a list to include in an object (along with a message if the removal was successful) to return.
When you use async lambda in a select, this return IEnumerable<Task<T>>. In you case, the variable userList is type of IEnumerable<Task<GetUsersModel>>. You need to wait all tasks and get the result like :
public IActionResult GetUsers()
{
var userDbList = _userManager.Users.ToList();
if (userDbList is null) return BadRequest(AppResources.UsersDoNotExist);
IEnumerable<Task<GetUsersModel>> userListTasks = userDbList.Select(async user => new GetUsersModel
{
Name = $"{user.FirstName} {user.LastName}",
UserName = user.UserName,
Email = user.Email,
Role = await _userManager.GetRolesAsync(user)
});
IEnumerable<GetUsersModel> userList = userListTasks.Select(t => t.Result);
return Ok(userList);
}
If the method UserManager.GetRolesAsync isn't thread safe, then :
public IActionResult GetUsers()
{
var userDbList = _userManager.Users.ToList();
if (userDbList is null) return BadRequest(AppResources.UsersDoNotExist);
IEnumerable<GetUsersModel> userList = userDbList.Select(user => new GetUsersModel
{
Name = $"{user.FirstName} {user.LastName}",
UserName = user.UserName,
Email = user.Email,
Role = _userManager.GetRolesAsync(user).Result
});
return Ok(userList);
}
I am trying to delete an already existing user from a database, which was created automatically when creating MVC application.
The database consists of tables:
AspNetUsers
AspNetUserRoles
AspNetUserLogins
AspNetUserClaims
AspNetRoles
In my code it looks like this:
var user = new ApplicationUser { UserName = model.email, Email = model.email };
var context = new ApplicationDbContext();
context.Users.Attach(user);
context.Users.Remove(user);
context.SaveChangesAsync();
return RedirectToAction("OperationSuccess", "Account");
I have also tried this:
var user = new ApplicationUser { UserName = model.email, Email = model.email };
var context = new ApplicationDbContext();
UserManager.DeleteAsync(user);
But it doesn't help at all. The application itselt does not break and does not show any errors, but the user is still in the database. How do I delete it?
Try this code:
public async Task<IdentityResult> DeleteUser(string email)
{
var user = UserManager.Users.FirstOrDefault(x => x.Email == email);
if(user == null) return null;
var result = await UserManager.DeleteAsync(user); //here result has two properties Errors and Succeeded.
return result;
}
Also, your code is not working because you are creating the object yourself and assigning only two properties yourself in spite of fetching the data from database.
Hi I think you have some versioning problem and its seems that you need to give one extra paramater to the DeleteAsync method.
Kindly refer the below link, since they had same kind of issue and resolved it.
https://stackoverflow.com/a/24594440/3397630
Hope it may give you some idea for your solution too.
Thanks
Karthik
Hope below code will help you to fix your problem
[HttpPost]
public async Task<ActionResult> Delete(string userId)
{
// Check for for both ID and exit if not found
if (String.IsNullEmpty(userId))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = UserManager.Users.SingleOrDefault(u => u.Id == Userid);
// Look for user in the UserStore
// If not found, exit
if (user == null)
{
return HttpNotFound();
}
var results = await UserManager.DeleteAsync(user); // Remove user from UserStore
// If the statement is a success
if (results.Succeeded)
{
// Redirect to Users page
return RedirectToAction("Index", "Users");
}
else
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
I'm testing some code which needs user to be logged in. When I'm trying to log in with AccountController, it's looks like everything is working, but at AccountController (IPrincipal) User is still null. How can I properly log in (or better, can I mock it somehow)?
public async Task SetupAsync()
{
var context = new DataContext();
var manager = new UserManager(new UserStore(context));
var accountController = new AccountController(manager);
var mockAuthenticationManager = new Mock<IAuthenticationManager>();
mockAuthenticationManager.Setup(am => am.SignOut());
mockAuthenticationManager.Setup(am => am.SignIn());
accountController.AuthenticationManager = mockAuthenticationManager.Object;
var user = new LoginViewModel
{
Email = "user#wp.pl",
Password = "useruser",
RememberMe = false
};
if (manager.FindByEmail("user#wp.pl") == null)
{
await manager.CreateAsync(new User { Email = "user#wp.pl", UserName = "user#wp.pl" }, "useruser");
}
await accountController.Login(user, "home/index");
_calendarController = new CalendarController(context);
}
Here I got User null exception:
public ClaimsPrincipal CurrentUser
{
get { return new ClaimsPrincipal((System.Security.Claims.ClaimsPrincipal)this.User); }
}
Edit: At return line, I have still User property null. This is sample from AccountController:
var user = await _userManager.FindAsync(model.Email, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
return RedirectToAction("index", "calendar");
}
You should mock your _userManager, and use a mock setup for when the method FindAsync is called. Then you return a fake user you can use later in the code
Figured it out on my own, probably not elegant solution but I'm happy anyway. #andreasnico your answer helped, thanks.
I'm mocking my custom ClaimsPrincipal, and setting up UserId - that's what I really needed.
var mockCp = new Mock<IClaimsPrincipal>();
mockCp.SetupGet(cp => cp.UserId).Returns(user.Id);
_calendarController.CurrentUser = mockCp.Object;
I have a controller action which i am performing some work on (example below)
public ActionResult Dashboard()
{
// Redirect back to login page if not authenticated
if (!this.HttpContext.User.Identity.IsAuthenticated)
{
return this.RedirectToAction(string.Empty, "Account");
}
this.ApplicationDbContext = new ApplicationDbContext();
this.UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(this.ApplicationDbContext));
var user = this.UserManager.FindById(this.User.Identity.GetUserId());
MyRitualDashboardData model = new MyRitualDashboardData();
Member member = db.Members.Single(m => m.AspNetUserId == user.Id);
model.Gravatar = string.Format("<img src='{0}' class='gravatar img-circle'/>", user.PhotoUrl);
model.UserMember = member;
model.UserHomeLocation = member.getUserHomeLocation();
model.UserActiveMembership = member.getActiveMembership();
model.UserPastMemberships = member.getExpiredMemberships();
model.UserPayments = member.getUserPayments();
model.UserStatistics = member.GetMembershipStatistics();
if (model.UserActiveMembership != null)
{
model.DaysTillMembershipExpiry = member.getActiveMembership().daysTillExpiry();
}
return this.View(model);
}
If i run this code and perform some changes to the database with some other actions then when i refresh my dashboard the various updates that i am making to the member profile is fine.
If however i try to re-factor my code and place the above code into a seperate class and use a static method to do the call like so:
public ActionResult Dashboard()
{
// Redirect back to login page if not authenticated
if (!this.HttpContext.User.Identity.IsAuthenticated)
{
return this.RedirectToAction(string.Empty, "Account");
}
this.ApplicationDbContext = new ApplicationDbContext();
this.UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(this.ApplicationDbContext));
var user = this.UserManager.FindById(this.User.Identity.GetUserId());
MyRitualDashboardData model = new MyRitualDashboardData();
model = MyRitualService.GetModelForMyRitual(user);
return this.View(model);
}
and have a method in a seperate class like so:
public static MyRitualDashboardData GetModelForMyRitual(ApplicationUser user)
{
MyRitualDashboardData model = new MyRitualDashboardData();
Member member = db.Members.Single(m => m.AspNetUserId == user.Id);
model.Gravatar = string.Format("<img src='{0}' class='gravatar img-circle'/>", user.PhotoUrl);
model.UserMember = member;
model.UserHomeLocation = member.getUserHomeLocation();
model.UserActiveMembership = member.getActiveMembership();
model.UserPastMemberships = member.getExpiredMemberships();
model.UserPayments = member.getUserPayments();
model.UserStatistics = member.GetMembershipStatistics();
if (model.UserActiveMembership != null)
{
model.DaysTillMembershipExpiry = member.getActiveMembership().daysTillExpiry();
}
return model;
}
Then it is using cached data from the database and i do not know why? Why would the same code called inline in the action be fine but when called from a seperate static function that it caches the data.
Any clues would be great.
Thanks
Both versions have the line
Member member = db.Members.Single(m => m.AspNetUserId == user.Id);
but since this is now in 2 different classes it must also be 2 different dbs.
The second one is static and will live longer (ie never refresh).
Avoid static. The separation in 2 classes is a good idea but just make instances.
Follow naming standards so that properties are easier to recognize.
I am struggling a bit with Asp.net Identity and updating a user. When I run the code below succeed is false and the error message is that the user with username exists. Which is - of course - obvious because you are updating a user, not creating a new one.
I have tried to remove the username without much success, I was then told that the Name (I believe it meant Username) could not be empty.
Snip of code below.
public async Task<ActionResult> Edit(RegisterViewModel model)
{
var user = new User()
{
UserName = model.UserName, FirstName = model.FirstName, LastName = model.LastName, Email = model.EmailAddress,
ApplicationId = Utilities.ApplicationUtilities.GetApplicationId()
};
var userContext = new ApplicationDbContext();
var userStore = new UserStore<User>(userContext);
var userManager = new UserManager<User>(userStore);
var result = await userManager.UpdateAsync(user);
if (result.Succeeded)
{
var selectedRole = model.SelectedRole;
if (!userManager.IsInRole(user.Id, selectedRole.Id))
{
// We are removing the user from the old role. He / she cannot have two or more roles
userManager.RemoveFromRole(user.Id, model.OldRole);
// Now we are adding the user to the new role
userManager.AddToRole(user.Id, selectedRole.Id);
userManager.Update(user);
}
userContext.SaveChanges();
// await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "UserManager");
}
The solution based on the input from Jonesy became something like this:
/*
* Some more information /Just in case someone else does the same
* mistakes I did...
*/
model.OldRole = "User"; // Name of old role - not ID of old role
model.SelectedRoleId = "Administrator"; // Name of new role, not ID of new role
// This test is here just to check if the model is valid or not
// By adding this part, you can check what is possibly wrong with your model
if (!ModelState.IsValid)
{
var errors = ModelState
.Where(x => x.Value.Errors.Count > 0)
.Select(x => new {x.Key, x.Value.Errors})
.ToArray();
}
// Creating the ApplicationDbContext object
var userContext = new ApplicationDbContext();
// Getting the list of users (I tried using Find here, but got errors)
var userList = userContext.Users.ToList();
// Decided to use First or Default. You also have to use double
// equal-characters(=) otherwise you will get errors
var user = userList.FirstOrDefault(u => u.UserName == model.UserName);
// Checking that we really found the user to update
if (user != null)
{
// populate the user object
user.UserId = model.UserId;
user.FirstName = model.FirstName;
user.LastName = model.LastName;
user.Email = model.EmailAddress;
}
// creating the UserStore object
var userStore = new UserStore<User>(userContext);
// ... and the userManager object
var userManager = new UserManager<User>(userStore);
// Do the update - I believe this is on the userManager-object
// and not in the database
var result = await userManager.UpdateAsync(user);
// If we get an error, we return to list of Users
// (You should log the error and also return the user to the form)
if (!result.Succeeded) return RedirectToAction("Index", "UserManager");
// Do the actual update in the database
userContext.SaveChanges();
// If the old role and the selected role is the same, we don't
// have to update
if (model.OldRole == model.SelectedRoleId) return RedirectToAction("Index", "UserManager");
// Get the selected role (sort of not needed, but here for clarity)
string selectedRole = model.SelectedRoleId;
// We are removing the user from the old role.
// In our application a user cannot have two or more roles
userManager.RemoveFromRole<User, string>(user.UserId, model.OldRole);
// Now we are adding the user to the new role
userManager.AddToRole<User, string>(user.UserId, selectedRole);
// We are updating the userManager-object
userManager.Update(user);
// And storing the information in the database
userContext.SaveChanges();
// Returning the user to the list of users
return RedirectToAction("Index", "UserManager");
use your dbContext to pull the user to update, instead of creating a new one:
var user = userContext.Find(model.UserName);
or you may need
var user = userContext.FirstOrDefault(u => u.UserName = model.UserName && u.Email = model.EmailAddress);
if(user != null)
{
//update user
}
this is an old one but just wanted to post my solution to the same update issue
var user = UserManager.FindByEmail(model.Email);
user.Address = model.Address;
user.City = model.City;
user.State = model.State;
var result = await UserManager.UpdateAsync(user);
you can also manage roles
user.Roles.Add(Role);
user.Roles.Remove(Role);