ASP.NET MVC: Custom identity fields - asp.net-mvc

How should I update custom made identity fields in ASP.NET MVC?
public class ApplicationUser : IdentityUser
{
public string customerName { get; set; }
public string customer_lastName { get; set; }
public string customer_phoneNumber { get; set; }
public string addressType { get; set; }
public string addressLine1 { get; set; }
public string addressLine2 { get; set; }
public string city { get; set; }
public string country { get; set; }
public string[] location_details { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
To be more specific, how am I supposed to update fields such as customerName,or customer_lastName after a value has been inserted in database for that field ?

Related

Table Value Function mapping with Entity Framework 6.3

How do I map table value functions in Code with Entity Framework 6.3? I'm trying to a DB Context in code with an existing database, because EDMX is currently not supported in ASP.NET Core 3. I've tried setting up my DbContext clasee as below. I can successfully query the Grade table. But when I try to query my function "fn_GetCatgeories", I get the following error: No EdmType found for type 'WebApplication6.Data.ApplicationContext+fn_GetCategories'.
public class ApplicationContext : DbContext
{
public ApplicationContext(string cstr)
: base(cstr)
{
Database.SetInitializer<ApplicationContext>(null);
}
[Table("Grade")]
public class Grade
{
[Key]
public string Grade_ID { get; set; }
public string SchoolType { get; set; }
public int Sortorder { get; set; }
}
public partial class fn_GetCategories
{
public int Category_ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Nullable<bool> Active { get; set; }
public Nullable<System.DateTime> Month { get; set; }
public Nullable<int> Order { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new FunctionsConvention<ApplicationContext>("dbo"));
base.OnModelCreating(modelBuilder);
}
[DbFunction("ApplicationContext", "fn_GetCategories")]
public IQueryable<fn_GetCategories> GetCategories(Nullable<System.DateTime> month)
{
var monthParameter = month.HasValue ?
new ObjectParameter("Month", month) :
new ObjectParameter("Month", typeof(System.DateTime));
return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<fn_GetCategories>(string.Format("[0].{1}", GetType().Name, "[fn_GetCategories](#Month)"), monthParameter);
}
// DbSets here
public DbSet<Grade> Grades { get; set; }
}
This works:
public class ApplicationContext : DbContext
{
public ApplicationContext(string cstr)
: base(cstr)
{
Database.SetInitializer<ApplicationContext>(null);
}
[Table("Grade")]
public class Grade
{
[Key]
public string Grade_ID { get; set; }
public string SchoolType { get; set; }
public int Sortorder { get; set; }
}
public partial class fn_GetCategories_Result
{
[Key]
public int Category_ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Nullable<bool> Active { get; set; }
public Nullable<System.DateTime> Month { get; set; }
public Nullable<int> Order { get; set; }
}
// DbSets here
public DbSet<Grade> Grades { get; set; }
public DbSet<fn_GetCategories_Result> fn_GetCategoriesSet { get; set; }
public List<fn_GetCategories_Result> fn_GetCategories(DateTime month)
{
var m = new SqlParameter("Month", DateTime.Now);
return this.fn_GetCategoriesSet.SqlQuery("select * from dbo.fn_GetCategories(#month)", m).ToList();
}

Entity Framework & Code First: Can't get data in one-to-one between ApplicationUser and UserProfile

I have custom ApplicationUser and create UserProfile, but can't get data UserProfile from ApplicationUser.
Attack Image:
Please refer to http://www.mediafire.com/file/a9bpajjc44fuewp/DemoMVC6.rar
Update my code:
namespace DemoMVC6.Models
{
// Add profile data for application users by adding properties to the ApplicationUser class
public class ApplicationUser : IdentityUser
{
public virtual UserProfile UserProfile { get; set; }
}
[Table("UserProfile")]
public class UserProfile : EntityBase
{
[Required, MinLength(3), MaxLength(20)]
public string FirstName { get; set; }
[Required, MinLength(3), MaxLength(20)]
public string LastName { get; set; }
public bool? Gender { get; set; }
public DateTime? Birthday { get; set; }
public string Address { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
public abstract class EntityBase
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual int Id { get; set; }
[EnumDataType(typeof(RecordStatus))]
public virtual RecordStatus ActiveStatus { get; set; }
[DataType(DataType.DateTime)]
public virtual DateTime CreatedOn { get; set; }
public virtual int CreatedBy { get; set; }
[DataType(DataType.DateTime)]
public virtual DateTime ModifiedOn { get; set; }
public virtual int ModifiedBy { get; set; }
}
public enum RecordStatus { Inactive = 0, Active = 1 }
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
public override int SaveChanges()
{
var currentTime = DateTime.Now;
var trackerEntries = this.ChangeTracker.Entries().Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);
//Find all Entities that are Added/Modified that inherit from my EntityBase
foreach (var entry in trackerEntries)
{
if (entry.State == EntityState.Added)
{
if (entry.Metadata.FindProperty("ActiveStatus") != null)
entry.Property("ActiveStatus").CurrentValue = RecordStatus.Active;
if (entry.Metadata.FindProperty("CreatedOn") != null)
entry.Property("CreatedOn").CurrentValue = currentTime;
if (entry.Metadata.FindProperty("ModifiedOn") != null)
entry.Property("ModifiedOn").CurrentValue = currentTime;
}
else
{
if (entry.Metadata.FindProperty("ModifiedOn") != null)
entry.Property("ModifiedOn").CurrentValue = currentTime;
}
}
return base.SaveChanges();
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
}

ApplicationDbContext.EntityName() returning null

Why db.Countries() comes null in following scenario-
1. CityController
[Authorize]
public class CityController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext("CP");
// GET: City/Create
public ActionResult Create()
{
ViewBag.CountryId = new SelectList(db.Countries.ToList(), "CountryId", "Name");
return View();
}
ApplicationDbContext
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
internal IDbSet<Country> Countries { get; set; }
...
}
Country is defined as-
[Table("Country")]
public class Country
{
#region Fields
private ICollection<City> _cities;
#endregion
#region Scalar Properties
public Guid CountryId { get; set; }
public string Name { get; set; }
public string CountryCode { get; set; }
#endregion
#region Navigation Properties
public virtual ICollection<City> Cities
{
get { return _cities ?? (_cities = new List<City>()); }
set { _cities = value; }
}
#endregion
}
City is defined as-
[Table("City")]
public class City
{
#region Fields
private ICollection<Location> _locations;
#endregion
#region Scalar Properties
public Guid CityId { get; set; }
public Guid CountryId { get; set; }
public string Name { get; set; }
public string CityCode { get; set; }
public string ZipCode { get; set; }
public Country Country { get; set; }
#endregion
#region Navigation Properties
public virtual ICollection<Location> Locations
{
get { return _locations ?? (_locations = new List<Location>()); }
set { _locations = value; }
}
#endregion
}
What could be the reason for not populating Country table records and returning countries to null?
After sparing few hours, I just noticed the Access-modifier of Countries properties which was internal. I made it Public and magic happened! It works though I don't have any explanation on WHY part of it.
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
//internal IDbSet<Country> Countries { get; set; }
public IDbSet<Country> Countries { get; set; }
public IDbSet<City> Cities { get; set; }
Thanks everyone.

UserManager Argument Type not within bounds

I'm rewriting an MVC3 application using MVC5 with EF6 and attempting to also migrate the membership and roles API to Identity 2. I've followed several guides but am now receiving build errors with which I need assistance.
My AccountController in part is as follows:
[Authorize]
public class AccountController : Controller
{
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager { get; private set; }
My UserManager is as follows:
public class UserManager : UserManager<User>
{
public UserManager()
: base(new UserStore<User>(new ApplicationDbContext()))
{
this.PasswordHasher = new SQLPasswordHasher();
}
}
My ApplicationDbContext is as follows:
public class ApplicationDbContext : IdentityDbContext<User>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
this.Database.Log = Logger;
}
private void Logger(string log)
{
Debug.WriteLine(log);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var application = modelBuilder.Entity<Application>();
application.HasKey(t => t.ApplicationId).ToTable("Applications");
modelBuilder.Entity<UserDbProfile>().ToTable("Profiles");
}
public virtual IDbSet<Application> Applications { get; set; }
public virtual IDbSet<UserDbProfile> Profiles { get; set; }
}
My User model is as follows:
public class User : IdentityUser
{
public User()
{
CreateDate = DateTime.UtcNow;
IsApproved = false;
LastLoginDate = DateTime.UtcNow;
LastActivityDate = DateTime.UtcNow;
LastPasswordChangedDate = DateTime.UtcNow;
LastLockoutDate = MinSqlDate;
FailedPasswordAnswerAttemptWindowStart = MinSqlDate;
FailedPasswordAttemptWindowStart = MinSqlDate;
Profile = new ProfileInfo();
}
public System.Guid ApplicationId { get; set; }
public bool IsAnonymous { get; set; }
public System.DateTime? LastActivityDate { get; set; }
public string Email { get; set; }
public string PasswordQuestion { get; set; }
public string PasswordAnswer { get; set; }
public bool IsApproved { get; set; }
public bool IsLockedOut { get; set; }
public System.DateTime? CreateDate { get; set; }
public System.DateTime? LastLoginDate { get; set; }
public System.DateTime? LastPasswordChangedDate { get; set; }
public System.DateTime? LastLockoutDate { get; set; }
public int FailedPasswordAttemptCount { get; set; }
public System.DateTime? FailedPasswordAttemptWindowStart { get; set;}
public int FailedPasswordAnswerAttemptCount { get; set; }
public System.DateTime? FailedPasswordAnswerAttemptWindowStart
{ get; set; }
public string Comment { get; set; }
public ProfileInfo Profile { get; set; }
private static readonly DateTime MinSqlDate =
DateTime.Parse("1/1/1754");
}
The specific errors received are similar to:
Error 16
Inconsistent accessibility: parameter type
'Microsoft.AspNet.Identity.UserManager' is less accessible than method
'Controllers.AccountController.AccountController(Microsoft.AspNet.
Identity.UserManager<Controllers.ApplicationUser>)'
Note that I've already created new tables in the database that migrated the old membership and roles for use with Identity 2.
What must be done to resolve the errors and ensure that the new Identity 2 methods are working correctly?
Update
My AccountController code is now as follows:
public AccountController()
: this(new UserManager(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
UserManager is as follows, in part:
public class UserManager : UserManager<User>
{
private UserStore<Controllers.ApplicationUser> userStore;
public UserManager()
: base(new UserStore<User>(new ApplicationDbContext()))
{
this.PasswordHasher = new SQLPasswordHasher();
}
}
Build error states:
Error 19 'UserManager' does not contain a constructor that takes 1 arguments
Note that the ApplicationUser controller was created but doesn't have any methods implemented. Is this controller, needed? Or, can I remove it and references to it?
Your AccountController needs to take your UserManager, not UserManager<ApplicationUser> which is part of the framework:
[Authorize]
public class AccountController : Controller
{
public AccountController()
: this(new UserManager(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}
public AccountController(UserManager userManager)
{
UserManager = userManager;
}
public UserManager UserManager { get; private set; }
Also I noticed that in controller you have ApplicationUser, but your user object is actually User. Make sure you are consistent with your classes.

many to many relation in asp.net mvc EF code first

I'm using asp.net mvc 4, EF, codefirst to make a many to many relation to a users and roles system
the user model:
public class User
{
#region properties
[Key]
public Int32 Id { get; set; }
[Required]
public String UserName { get; set; }
public String Password { get; set; }
[Required]
public String Email { get; set; }
public DateTime CreationDate { get; set; }
public DateTime LastUpdate { get; set; }
public DateTime? LastLogin { get; set; }
[ForeignKey("RoleId")]
public virtual ICollection<Role> Roles { get; set; }
#endregion //properties
#region constructors
public User()
{
Roles = new HashSet<Role>();
LastUpdate = DateTime.Now;
CreationDate = DateTime.Now;
}
#endregion //constuctors
}
the role model:
public class Role
{
[Key]
public Int32 Id { get; set; }
public String Name { get; set; }
public String Description { get; set; }
public DateTime CreationDate { get; set; }
public DateTime LastUpdate { get; set; }
[ForeignKey("UserId")]
public virtual ICollection<User> Users { get; set; }
public Role()
{
Users = new HashSet<User>();
CreationDate = DateTime.Now;
LastUpdate = DateTime.Now;
}
}
the context:
public class UserManagementContext : Context, IContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public UserManagementContext() {
Database.SetInitializer<UserManagementContext>(null);
}
void IContext.Setup(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<Role>().ToTable("Roles");
modelBuilder.Entity<User>()
.HasMany(u => u.Roles)
.WithMany(r => r.Users)
.Map(
m =>
{
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
m.ToTable("UserRoles");
});
}
}
When the database tables are generated the tables users, roles and userroles are there. Then I make a record in users, one in roles and one in userroles to connect those. The userroles table has two columns RoleId and UserId.
Then I try to load the roles of a user like this:
public String[] GetRoles(String userName)
{
//var user = ConcreteContext.Users.Include("Roles").Where(u => u.UserName == userName).FirstOrDefault();
var users = ConcreteContext.Users.Include(u => u.Roles);
var user = users.FirstOrDefault();
var roles = from r in user.Roles
select r.Name;
return roles.ToArray();
}
But the line with var users = ConcreteContext.Users.Include(u => u.Roles); raises the next error:
System.Data.SqlClient.SqlException: Invalid object name 'dbo.RoleUsers'.
If I change de table name of UserRoles to RoleUsers when de database is created (by using m.ToTable(RoleUsers) ), I get a lot of different errors about wrong field names.
Anyone an idea what I'm missing here?
Thanks in advance,
Willem
Any reason why you have to use the Fluent API?
You can map Many-to-many like this with data attributes:
public class User
{
[InverseProperty( "Users" )]
public virtual ICollection<Role> Roles {get;set;}
}
public class Role
{
[InverseProperty( "Roles" )]
public virtual ICollection<User> Users {get;set;}
}
This will do what I needed:
public class User
{
#region properties
[Key]
public Int32 Id { get; set; }
[Required]
public String UserName { get; set; }
public String Password { get; set; }
[Required]
public String Email { get; set; }
public DateTime CreationDate { get; set; }
public DateTime LastUpdate { get; set; }
public DateTime? LastLogin { get; set; }
[InverseProperty("Users")]
public virtual ICollection<Role> Roles { get; set; }
#endregion //properties
#region constructors
public User()
{
LastUpdate = DateTime.Now;
CreationDate = DateTime.Now;
}
#endregion //constuctors
}
public class Role
{
[Key]
public Int32 Id { get; set; }
public String Name { get; set; }
public String Description { get; set; }
public DateTime CreationDate { get; set; }
public DateTime LastUpdate { get; set; }
[InverseProperty("Roles")]
public virtual ICollection<User> Users { get; set; }
public Role()
{
CreationDate = DateTime.Now;
LastUpdate = DateTime.Now;
}
}
public class UserManagementContext : Context, IContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public UserManagementContext() {
Database.SetInitializer<UserManagementContext>(null);
}
void IContext.Setup(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<Role>().ToTable("Roles");
}
}

Resources