12

I am using asp.net identity to create new user but getting error:

Cannot insert the value NULL into column 'Id', table 'Mydb.dbo.AspNetUsers'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated

But here I don't have any such table like AspNetUsers but instead I have my own table that is Users.

Code: Web.config: 2 conection strings

 <add name="myEntities" connectionString="metadata=res://*/DataModel.csdl|res://*/DataModel.ssdl|res://*/DataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=;initial catalog=mydb;user id=sa;password=sdfsdfsdf;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
 <add name="MyConnString" connectionString="data source=;initial catalog=Mydb;user id=sa;password=sdfsdfsdf;" providerName="System.Data.SqlClient" />

IdentityModel.cs:

public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            this.SecurityStamp = Guid.NewGuid().ToString();
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }

        public string Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public virtual string Email { get; set; }
        public string Password { get; set; }
        public string Role { get; set; }
        public Nullable<bool> IsActive { get; set; }
        public Nullable<int> CreatedBy { get; set; }
        public Nullable<System.DateTime> CreatedDate { get; set; }
        public Nullable<System.DateTime> LastLogin { get; set; }

        public ApplicationUser()
        {

        }

        public ApplicationUser(string email, string firstName, string lastName, string designation, bool isActive)
        {
            Email = email;
            FirstName = firstName;
            LastName = lastName;
            Designation = designation;
            IsActive = isActive;
        }
    }
  public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("MyConnString", throwIfV1Schema: false)
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }

UserStore1.cs:

public class UserStore1 : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>
    {
        private readonly HttpContext _httpContext;
        UserStore<IdentityUser> userStore = new UserStore<IdentityUser>(new ApplicationDbContext());

        public System.Threading.Tasks.Task CreateAsync(ApplicationUser user)
        {
            HttpContext.Current = _httpContext ?? HttpContext.Current;
            var context = userStore.Context as ApplicationDbContext;
           context.Users.Add(user);
           context.Configuration.ValidateOnSaveEnabled = false;
           context.SaveChanges();
            return Task.FromResult(true);
        }
     }

Controller:

     [Authorize]
    public class AccountController : Controller
    {
        public AccountController()
            : this(new UserManager<ApplicationUser>(new UserStore1()))
        {
        }

        public AccountController(UserManager<ApplicationUser> userManager)
        {
            UserManager = userManager;
        }
        public UserManager<ApplicationUser> UserManager { get; private set; }
[HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(string email, string password, bool rememberMe = false, string returnUrl = null)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser
                {
                    FirstName= "Abc",
                    LastName= "Pqr",
                    UserName="Abc@yahoo.com",
                    SecurityStamp = Guid.NewGuid().ToString()
                };

                var result= await UserManager.CreateAsync(user,"123456");
            }
            return View();
        }
    }

Note: I have autogenerated Id in my database table field and that Id is Int.

Update: I am using database first(edmx) and the table that I am using are custom tables for inserting new records(for eg:Users).

At first I have implemented microsoft asp.net identity as shown in below question but 1 user pointed out that I am not using ApplicationUser class which is responsible for handling sign in,cookies etc so I am now trying to use ApplicationUser class:

How to give custom implementation of UpdateAsync method of asp.net identity?

I am really now regretting over my decision to choose Microsoft Identity Framework for Authentication purpose as because I am really finding it complex but now as I have move forward I have to go with it.

halfer
  • 19,824
  • 17
  • 99
  • 186
I Love Stackoverflow
  • 6,738
  • 20
  • 97
  • 216
  • It seems to me that you're missing something. You haven't defined your model in `OnModelCreating` for your `ApplicationDbContext`. Check this [answer](http://stackoverflow.com/a/37000105/219406) – LeftyX Sep 04 '16 at 16:06
  • @LeftyX sorry but I am not using code first.i am using databse first(.edmx) and I have already seen some of your answers and infact tried it but unfortunately you have used code first and I am using edmx – I Love Stackoverflow Sep 04 '16 at 17:55
  • 1
    I don't have much time these days but I'll have a look into this over the weekend. If you could isolate the code and share it somewhere it would be helpful. Cheers. – LeftyX Sep 08 '16 at 07:39
  • @LeftyX:Yeah sure.if you want i can send you my project which contains only microsoft identity implementation and database script so you can take a look.can i send you link for both of that to download or what you want ?? – I Love Stackoverflow Sep 08 '16 at 07:49
  • 1
    Please do. Publish it somewhere so that I can download it. Cheers. – LeftyX Sep 08 '16 at 08:23
  • Is your Id property defined as primary key in your database ? – Béranger Sep 14 '16 at 07:23
  • @Béranger:Yeah Id property is defined as primary key in database with autoincrement setting – I Love Stackoverflow Sep 14 '16 at 07:39

1 Answers1

7

The inconsistency i found, in ApplicationUser class you are declaring property Idand Email which is wrong because the IdentityUser class already have those properties. This may arise the issue. But you can override them if necessary. Also the constructor you are using isn't necessary. The ApplicationUser class should be:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        this.SecurityStamp = Guid.NewGuid().ToString();
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }    
    public string Password { get; set; }
    public string Role { get; set; }
    public bool? IsActive { get; set; }
    public int? CreatedBy { get; set; }
    public DateTime? CreatedDate { get; set; }
    public DateTime? LastLogin { get; set; }

}

Second thing, you are creating the user inside Login action which is also not valid. you should do it inside Register action. Following in an example:

 public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
          var user = new ApplicationUser
            {
                FirstName = "Abc",
                LastName = "Pqr",
                UserName = "Abc@yahoo.com",
                Email= model.Email,
                Password= model.Password,
                PasswordHash = UserManager.PasswordHasher.HashPassword(model.Password),
                SecurityStamp = Guid.NewGuid().ToString()
            };

            var result = await UserManager.CreateAsync(user);
        if (result.Succeeded)
            {
                await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);                    
                return RedirectToAction("Index", "Home");
            }
            AddErrors(result);
        }

        return View(model);
    }

Hope this will help :)

Mahbubur Rahman
  • 4,961
  • 2
  • 39
  • 46