16

I have created my data layer with EF 6 code first and I am populating the db through Seed method of EvInitializer class inheriting from DropCreateDatabaseIfModelChanges. The implementation of Seed method is

protected override void Seed(EvContext context)
{
   //Add other entities using context methods
   ApplicationUserManager manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context));
   var user = new ApplicationUser { Email = "admin@myemail.com" ,UserName = "admin@myemail.com"};
   var result = await manager.CreateAsync(user, "Temp_123");//this line gives error. obviously await cannot be used in non- async method and I cannot make Seed async
}

My question is how I can add a user in Seed method using UserManager class. when I change var result = awit manager.CreateAsync(user, "Temp_123");
to
var result = manager.CreateAsync(user, "Temp_123").Result; //or .Wait
the application hangs indefinitely

tmg
  • 19,895
  • 5
  • 72
  • 76
Muhammad Adeel Zahid
  • 17,474
  • 14
  • 90
  • 155

2 Answers2

19

In asp.net-identity-2 usermanager has non async methods to create.

var user = new ApplicationUser { Email = "admin@myemail.com", UserName = "admin@myemail.com" };
manager.Create(user, "Temp_123");

Same for rolemanager if you want to create "admin" role.

var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
roleManager.Create(new Role("admin"));

make the user admin

manager.AddToRole(user.Id, "admin");

Edit: As trailmax commented, Create() extension method comes in with Microsoft.AspNet.Identity namespace so do not forget using Microsoft.AspNet.Identity

tmg
  • 19,895
  • 5
  • 72
  • 76
  • There is no `manager.Create` method. I have checked from my installed nuget packages and I have version 2.1.0 of `Microsoft.AspNet.Identity.Core`. Any ideas? – Muhammad Adeel Zahid Dec 16 '14 at 08:34
  • I have 2.1.0 version too in my project and I can navigate to those 2 extension methods. Maybe try re-install packages – tmg Dec 16 '14 at 08:51
  • reinstalled the package using `Update-Package -reinstall Microsoft.AspNet.Identity.Core` but still there is no synchronous method for creating user in `ApplicationUserManager`. I am using Identity with web api, if that matters? – Muhammad Adeel Zahid Dec 16 '14 at 08:58
  • 1
    the sync versions of classes are extension methods coming from `Microsoft.AspNet.Identity.UserManagerExtensions` class. Check your namespace imports. – trailmax Dec 16 '14 at 10:33
  • You should add to your answer that a `using Microsoft.AspNet.Identity;` needs to be added so the `.Create()` extension method can be found. – QuantumHive Feb 17 '15 at 18:13
  • 1
    This works. Curiously Create will not allow spaces in the UserName and fails with out an error. More curiously CreateAsync, as used in the Register method of the AccountsController, does allow spaces. – Joe Dec 03 '15 at 23:15
7

TMG is correct - there are non-async methods available, and that's the easiest way in this particular case.

In general, however - when you you only have an async version of a function available to you, and you can't change the implementation of the method to be Async - you can create a task and wait for it synchronously.

So - instead of:

IdentityResult result = await manager.CreateAsync(user, "Temp_123");

You can code:

Task<IdentityResult> createTask = manager.CreateAsync(user, "Temp_123");
createTask.Wait();

Once the Wait has finished, the IdentityResult gets returned in

createTask.Result

You can also set a timeout on the Wait, like this:

Task<IdentityResult> createTask = manager.CreateAsync(user, "Temp_123");
if (!createTask.Wait(5000)) // Wait up to 5 seconds
{
   // We've timed out waiting - Do some error handling
}
else if (!createTask.Result.Succeeded)
{
  // Creating the user failed - Do some error handling
}
Steven Cowles
  • 79
  • 1
  • 3