2016-12-20 2 views
-1

ich dieseZuweisen einer Rolle zu einem Benutzer führt zu einer neuen Rolle in der Datenbank zu erstellen

[HttpPost, ValidateAntiForgeryToken] 
    public ActionResult Create(UserNew form) 
    { 
     var user = new User(); 
     SyncRoles(form.Roles, user.Roles); 

     if (db.Users.Any(u => u.username == form.username)) 
     { 
      ModelState.AddModelError("Username", "Username must be unique"); 
     } 

     if (ModelState.IsValid) 
     { 
      user.username = form.username; 
      user.email = form.email;     
      user.SetPassword(form.password); 

      db.Users.Add(user); 
      db.SaveChanges(); 

      return RedirectToAction("Index"); 
     } 

     return View(form); 
    } 

und mit dieser Funktion bekommen haben Ich versuche, das Kontrollkästchen zu bekommen in Form geprüft und die geprüften Rollen zuweisen für den Benutzer:

private void SyncRoles(IList<RoleCheckbox> checkboxes, IList<Role> roles) 
    { 
     var selectedRoles = new List<Role>(); 
     RolesContext rdb = new RolesContext(); 


     List <Role> roleList = new List<Role>(); 
     roleList = rdb.Roles.ToList(); 


     foreach (var role in roleList) 
     { 
      var checkbox = checkboxes.Single(c => c.roleId == role.roleId); 
      checkbox.roleName = role.roleName; 

      if (checkbox.IsChecked) 
       selectedRoles.Add(role); 
     } 
     foreach (var toAdd in selectedRoles.Where(t => !roles.Contains(t))) 
     { 
      roles.Add(toAdd); 
     } 
     foreach (var toRemove in roles.Where(t => !selectedRoles.Contains(t)).ToList()) 
     { 
      roles.Remove(toRemove); 
     } 
    } 

Wenn ich versuche, um den Benutzer zu erstellen, habe ich die Rolle „admin“ wählen Sie in der Datenbank, erhalte ich ein neues Feld (das in der Datenbank mit der ID = 1 ist bereits vorhanden) in der Rollen Tabelle mit dem Namen "admin" aber einer anderen ID. Kann mir jemand helfen zu verstehen, was ich falsch mache?

public class User 
{ 
    [HiddenInput(DisplayValue = false)] 
    public int userId { get; set; } 

    [Required] 
    [StringLength(128)] 
    public string username { get; set; } 

    [Required, DataType(DataType.EmailAddress)] 
    [StringLength(256)] 
    public string email { get; set; } 

    [Required] 
    [StringLength(128)] 
    public string password_hash { get; set; } 

    public virtual IList<Role> Roles { get; set; } 

    public User() 
    { 
     Roles = new List<Role>(); 
    } 

    public void SetPassword(string password) 
    { 
     password_hash = BCrypt.Net.BCrypt.HashPassword(password, 14); 
    } 
    public virtual bool CheckPassword(string password) 
    { 
     return BCrypt.Net.BCrypt.Verify(password, password_hash); 
    }   
} 

.

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<User>() 
      .Property(e => e.username) 
      .IsUnicode(false); 

     modelBuilder.Entity<User>() 
      .Property(e => e.email) 
      .IsUnicode(false); 

     modelBuilder.Entity<User>() 
      .Property(e => e.password_hash) 
      .IsUnicode(false); 

     modelBuilder.Entity<User>().HasMany(r => r.Roles).WithMany().Map(m => 
       { 
        m.ToTable("role_users"); 
        m.MapLeftKey("user_Id"); 
        m.MapRightKey("role_Id"); 
       }); 
    } 
+0

erstellen. Warum speichern Sie alles in Ihrer 'Roles' Tabelle? Sie müssen die mit einem Benutzer verbundenen Rollen in einer 'UserRoles' Tabelle speichern. –

+0

@StephenMuecke ja, das ist, was ich dachte, ich habe getan ... Wenn ich einen Breakpoint auf die Funktion 'SyncRoles (form.Roles, user. Rollen); Im ActionResult bekomme ich die korrekten Werte für user.Roles - RoleId = 1 und RoleName = "admin" ... – ricky

+0

Nein, nein. Sie haben eine Eigenschaft 'IList Roles', aber es muss' IList Roles' sein - Sie benötigen eine Tabelle für 'UserRoles', um die M-M-Beziehungen zu erstellen (mit FK-Feldern für' UserID' und 'RoleID'). Und als Nebenbemerkung macht fast alles, was du tust, keinen Sinn, und ich schlage vor, du liest [diese Antwort] (http://stackoverflow.com/questions/29542107/pass-list-of-checkboxes-into-view-and) -pull-out-iienumerable/29554416 # 29554416) für, wie Ihre Modelle und Ansicht aussehen sollte –

Antwort

0

Ich möchte einen Kommentar hinzufügen, ist aber nur nach 50+ Ruf möglich. Von dem, was ich in Ihrem Code sehe, weisen Sie dem Benutzer Rollen von MVC zu und Sie senden direkt an EF, die Sie auf Dubletten in der Datenbank führen. Sie sollten die Logik ändern, und nachdem Sie Benutzer mit Erfolg zu schaffen, sollten Sie UserManager Klasse verwenden Benutzer Rolle hinzufügen:

UserManager.AddToRole(user.Id, role.Name); 

wo Rolle gegen Datenbank überprüft wird. Wenn Sie keine Rolle in der Datenbank finden, sollten Sie sie mit IdentityRol e Klasse

Verwandte Themen