create user in migration Up() using Identity Framework - asp.net-mvc

I have added a migration to create a user but the code hangs when it hits userRepo.Create(...) and within this method at _userManager.Create(...)
using (UserRepository userRepo = new UserRepository())
{
User adminUser = new User() { IsActive = true, UserName =
"admin#testing.com", CompanyId = 1, Password =
"admintesting" };
adminUser.Role = new Models.Security.Role() { Id = 2 };
userRepo.Create(adminUser);
}
Create method is below
public IdentityResult Create(Model.User user)
{
var userEntity = Mapper.Map<Entity.Security.User>(user);
_dbContext.Set<Entity.Security.User>().Add(userEntity);
var result = _userManager.Create(userEntity, userEntity.Password);
DetachAllEntities();
return result;
}
_dbContext is inherited from IdentityDbContext and instantiated accordingly
UserManager<Entity.Security.User, int> _userManager = new UserManager<Entity.Security.User, int>(new UserStore<Entity.Security.User, Entity.Security.Role, int, Entity.Security.UserLogin, Entity.Security.UserRole, Entity.Security.UserClaim>(_dbContext));
The equivalent async method works elsewhere in the application but I would like the non-async for the migration sake. Any help is highly appreciated.

Related

how validate data that is not send by Post method?

i have a static object in controller that will be fill in some level of registration forms.finally i want to validate this object by modelstate method but is not possible because that is not send by post method..i am searching a standard way to validate..
public class AccountController : Controller
{
private MyDb db = new MyDb();
private static Trainer trainer = new Trainer();
public Trainer InfoSave(Trainer info)
{
trainer.SchoolGrade = info.SchoolGrade;
trainer.SchoolMajor = info.SchoolMajor;
trainer.MajorId = info.Major.Id;
trainer.History = info.History;
trainer.Major = info.Major;
if (ModelState.IsValid)
return true;
else
return false;
}
You can use some Third party library for loosely couple the validation logic. I am using FluentValidation library. You can utilize it:
using FluentValidation;
public class TrainerValidator : AbstractValidator<Trainer> {
public TrainerValidator() {
RuleFor(c=> c.Name).NotNull().WithMessage("Name is required");
}
}
public class AccountController : Controller
{
private MyDb db = new MyDb();
private static Trainer trainer = new Trainer();
public Trainer InfoSave(Trainer info)
{
trainer.SchoolGrade = info.SchoolGrade;
trainer.SchoolMajor = info.SchoolMajor;
trainer.MajorId = info.Major.Id;
trainer.History = info.History;
trainer.Major = info.Major;
TrainerValidator validator = new TrainerValidator();
ValidationResult result = validator.Validate(trainer);
if (result.IsValid)
return true;
else
return false;
}
You can extend it based on your requirements. Here is the link for the same FluentValidation

Testing a method in MVC which makes calls to Repositories

I have a MVC method like so:
public ActionResult ChangeStatus(string productId, string statusToChange)
{
var productToChangeStatus = _updateProductRepository.GetUpdateProduct(productId);
if (statusToChange.ToLower() == ChangeStatusTo.Disable)
{
productToChangeStatus.Active = "false";
}
else
{
productToChangeStatus.Active = "true";
}
_updateProductsManager.UpsertProduct(productToChangeStatus);
return Json(new { success = true });
}
This method gets an existing product based on the 'productId', changes the 'Active' property on it based on the 'statusToChange' value, saves it back and returns a Json with success.
The test setup is like so:
private ProductController _controller;
private Mock<IUpdateProductRepository> _iProductRepository;
[TestInitialize]
public void TestSetup()
{
_iProductRepository = new Mock<IUpdateProductRepository>();
_controller = new ProductController(_iProductRepository.Object);
}
Wrote a test method like so:
[TestMethod]
public void Disable_A_Product_Which_Is_Currently_Enabled()
{
const string productId = "123";
var productBeforeStatusChange = new Product()
{
Active = "true",
Id = new Guid().ToString(),
Name = "TestProduct",
ProductId = "123"
};
var productAfterStatusChange = new Product()
{
Active = "false",
Id = new Guid().ToString(),
Name = "TestProduct",
ProductId = "123"
};
_iProductRepository.Setup(r => r.GetUpdateProduct(productId)).Returns(productBeforeStatusChange);
_iProductRepository.Setup(r => r.UpsertProduct(productBeforeStatusChange)).Returns(productAfterStatusChange);
var res = _controller.ChangeStatus("123", "disable") as JsonResult;
Assert.AreEqual("{ success = true }", res.Data.ToString());
}
The test fails with this error:
Object reference not set to an instant of the object.
On debugging I found that it fails inside the
if(...)
condition where the actual setting of the Active property is happening.
Since the productId that's being passed is not real a product object can't be retrieved for the code to work on.
I tried to use Mock but I think my usage is not correct.
So what I want to know is, how to test a method like this where a method that returns an ActionResult is in turn calling the repository to work with object(s).
Thanks in advance.
You seems to be missing setup for
_updateProductsManager.UpsertProduct()
The way you setup GetUpdateProduct() method you ought to setup UpsertProduct() on the mock instance.

MVC 5 seeding users only works for email

I am working on a porject built on MVC5 and EF Code First.
I have multiple contexts, but the one I'm concered about here is the ApplicationDbContext which has the following configuration code:
namespace DX.DAL.Migrations.ApplicationDbMigrations
{
public class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
MigrationsDirectory = #"Migrations\ApplicationDbMigrations";
ContextKey = "DX.DAL.Context.ApplicationDbContext";
}
protected override void Seed(ApplicationDbContext context)
{
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
if (!roleManager.RoleExists("Admin"))
{
roleManager.Create(new IdentityRole("Admin"));
}
var user = new ApplicationUser { UserName = "John", Email = "j.doe#world.com" };
if (userManager.FindByName("John") != null) return;
var result = userManager.Create(user, "Password123#");
if (result.Succeeded)
{
userManager.AddToRole(user.Id, "Admin");
}
}
}
}
When I try and login with the email and password seeded above, I get the error:
Invalid login attempt
I wrote the following SQL Query:
SELECT * FROM AspNetUsers
And I see the following:
So the seed has been created. But why can't I login?
Also, I know that if I change the Username to be the same as the email, then it works and I can login. Must the username and email be the same for ASP.NET Membership in MVC 5 to work?
After trying so many different things, I went with LukeP's solution here.
I left Identity as it is and just added a new property called DisplayUsername and allowed the user to set that up on registration.

User.Identity.Name in Web Api Controller

I went through the answer to some of the already existing questions and none of the answers are working for me.
In the ProfileController, I invoke the WebApi Controller as follows:
public ViewResult Index()
{
var client = new HttpClient();
var webApiUrl = ConfigurationManager.AppSettings["WebApiURL"];
var response = client.GetAsync(string.Format("{0}{1}", webApiUrl, "//api/ProfileWeb")).Result;
var profile = response.Content.ReadAsAsync<Profile>().Result;
if (profile != null)
{
_profileModel.Id = profile.Id;
_profileModel.FirstName = profile.FirstName;
_profileModel.LastName = profile.LastName;
_profileModel.PhoneNumber = profile.PhoneNumber;
_profileModel.EmailAddress = profile.EmailAddress;
}
return this.View(_profileModel);
}
In the Api Contoller, I get the userName as follows:
public class ProfileWebController : ApiController
{
private IReminderDb _db;
public ProfileWebController(IReminderDb db)
{
_db = db;
}
public object Get()
{
string userName = User.Identity.Name; // <-- Not working..
var profile = _db.GetProfile(userName);
return profile;
}
}
Inside the web api controller, I am not able to get the User.Identity.Name that is in the ProfileContoller. According to some other answers where I have tried Thread.CurrentPrincipal but still the User.Identity.Name is coming out as null in web api controller.
What am I missing?

Save userid on database when create new object

I have a Controller where on the Create action I need the user ID.
Here's the controller.
public ActionResult Create(MyCreateViewModel model)
{
if (ModelState.IsValid)
{
var myobject = new MyObject
{
Attrib1 = DateTime.Now.Date,
Attrib2 = model.Etichetta,
UserId = // I need the user ID...
};
// Save the object on database...
return RedirectToAction("Index");
}
return View(model);
}
I'm using the UserProfile table provided with the SimpleMembership of MVC 4.
Which is the best practice in MVC 4 to manage the userID across the application?
Do I have to include a User attribute inside every Entity class?
Should I use a Session[] variable or what?
You can use this line to get the userId from the UserProfiles table.
var userId = WebSecurity.GetUserId(HttpContext.Current.User.Identity.Name);
You can also use this function to get the users complete profile, including any custom columns you may be populating.
public static UserProfile GetUserProfile()
{
using (var db = new UsersContext())
{
var userId = WebSecurity.GetUserId
(HttpContext.Current.User.Identity.Name);
var user = db.UserProfiles
.FirstOrDefault(u => u.UserId == userId);
if (user == null)
{
//couldn't find the profile for some reason
return null;
}
return user;
}
}

Resources