I am working on forms Authnetication, where i have used my own Entity Framework and also i have used the DataContext for giving the roles for the users. I have hardcoded the DataCOntectInitializer as below
public class DataContextInitializer : CreateDatabaseIfNotExists { protected override void Seed(DataContext context) { Roles role1 = new Roles { RoleName = "Admin" }; Roles role2 = new Roles { RoleName = "User" };
User user1 = new User { Username = "admin", EmailId = "[email protected]", FirstName = "Admin", Password = "123456", IsActive = true, DateCreated = DateTime.UtcNow, Roles = new List<Roles>() };
User user2 = new User { Username = "user1", EmailId = "[email protected]", FirstName = "User1", Password = "123456", IsActive = true, DateCreated = DateTime.UtcNow, Roles = new List<Roles>() };
user1.Roles.Add(role1);
user2.Roles.Add(role2);
context.Users.Add(user1);
context.Users.Add(user2);
context.SaveChanges();
}
}
And my Login Method is :
[HttpPost] [AllowAnonymous]
public ActionResult Login(LoginViewModel model, string returnUrl=" ")
{
if (ModelState.IsValid)
{
var user1 = Context.Users.Where(u => u.Username == model.Username && u.Password == model.Password).FirstOrDefault();
var user = ob.Users.Where(u => u.Username == model.Username && u.Password == model.Password).FirstOrDefault();
if (user != null)
{
var roles = user.Roles.Select(m => m.RoleName).ToArray();
CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
serializeModel.UserId = user.UserId;
serializeModel.FirstName = user.FirstName;
serializeModel.LastName = user.LastName;
serializeModel.roles = roles;
string userData = JsonConvert.SerializeObject(serializeModel);
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, user1.EmailId, DateTime.Now, DateTime.Now.AddMinutes(15), false, userData);
string encTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
Response.Cookies.Add(faCookie);
if ( roles.Contains("Admin"))
{
return RedirectToAction("Index", "Admin");
}
else if (roles.Contains("User"))
{
return RedirectToAction("Index", "User");
}
else
{
return RedirectToAction("Index", "Home");
}
}
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
And my Model classes are as below:
public class User {
public int UserId { get; set; }
[Required]
public String Username { get; set; }
[Required]
public String EmailId { get; set; }
[Required]
public String Password { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public Boolean IsActive { get; set; }
public DateTime DateCreated { get; set; }
public virtual ICollection<Roles> Roles { get; set; }
}
and
public class Roles {
[Key]
public int RoleId { get; set; }
[Required]
public string RoleName { get; set; }
public string Description { get; set; }
public virtual ICollection<User> Users { get; set; }
}
The problem is like when im trying to login using my username and password, the roles need to be checked from the DatContext class.
But at that time my Roles are not comin from DataContext class, and it is giving ArgumentNullException.
See this article answered by @Oliboy50 (Entity Framework 6 - Handling loading of nested objects) this might help, you need to include your virtual Roles so that the collection gets loaded