I was following the tutorial on this page, about how to add roles to users programatically in C# MVC. However, when the code executes I get the following error:
System.InvalidOperationException was unhandled by user code
HResult=-2146233079
Message=UserId not found.
Source=Microsoft.AspNet.Identity.Core
StackTrace:
at Microsoft.AspNet.Identity.UserManager`2.<AddToRoleAsync>d__83.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNet.Identity.AsyncHelper.RunSync[TResult](Func`1 func)
at Microsoft.AspNet.Identity.UserManagerExtensions.AddToRole[TUser,TKey](UserManager`2 manager, TKey userId, String role)
at SchoolRegistration.Controllers.AccountController.RoleAddToUser(FormCollection collection) in c:\Users\Kyle\Documents\Visual Studio 2013\Projects\SchoolRegistration\SchoolRegistration\Controllers\AccountController.cs:line 98
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
InnerException:
But I can't figure out what is causing this error. Any help would be appreciated.
Code:
Inside my account controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RoleAddToUser(FormCollection collection)
{
string UserName = collection["UserName"];
string RoleName = collection["RoleName"];
using (var context = new ApplicationDbContext()) {
ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var user2 = new ApplicationUser() { UserName = UserName };
var roleStore = new RoleStore<IdentityRole>(context);
var roleManager = new RoleManager<IdentityRole>(roleStore);
var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);
userManager.AddToRole(user2.Id, RoleName);
var account = new AccountController();
//account.UserManager.AddToRole(user.Id, RoleName);
ViewBag.ResultMessage = "Role added successfully.";
var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
ViewBag.Roles = list;
}
return View("ManageUserRoles");
}
UPDATE:
Ok so after taking everyone's suggestions I have reworked my code to look like the following:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RoleAddToUser(FormCollection collection)
{
string UserName = collection["UserName"];
string RoleName = collection["RoleName"];
using (var context = new ApplicationDbContext()) {
ApplicationUser user = context.Users.Where(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
var user2 = UserManager.FindByNameAsync(UserName);
var roleStore = new RoleStore<IdentityRole>(context);
var roleManager = new RoleManager<IdentityRole>(roleStore);
var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);
userManager.AddToRole(user2.Id.ToString(),RoleName);
var account = new AccountController();
//account.UserManager.AddToRole(user.Id, RoleName);
ViewBag.ResultMessage = "Role added successfully.";
var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
ViewBag.Roles = list;
}
return View("ManageUserRoles");
}
The weird thing is, I'm getting the exact same error. However, when I hover over my parameter now, it does in fact have a valid id and not null:
I did notice the value I receive when debugging is not the same as the value in the database (this could be due to hashing security?)
DB Value: 0752a8d8-fb0e-44d9-b8b0-57ccbbff826b
UPDATE 2:
For anyone having the same problem with the ids not matching, try using the FindByName method instead of FindByNameAsync. Worked for me!