8

Tôi đang sử dụng dự án mẫu này (https://github.com/imranbaloch/ASPNETIdentityWithOnion) làm kiến ​​trúc ứng dụng của mình, trong mẫu này lõi được giải mã hoàn toàn từ cơ sở hạ tầng bao gồm khung định danh.Phân tách ASP.NET Identity từ các mô hình miền chính - Kiến trúc Onion

Trong mẫu này tác giả đã sử dụng mẫu bộ điều hợp để phân tách các lớp nhận dạng lõi (IdentityUser, IdentityRole ...) và cung cấp các lớp giống như chúng trong lớp lõi.

Bây giờ vấn đề trong dự án mẫu này là Mô hình miền (Sản phẩm, Hình ảnh) không được liên kết với các lớp giả (AppUser, ApplicationRole, AppliationUserRoles, ...) bắt chước các định danh.

Sau đó, tôi đã sửa đổi mã để thêm các tài liệu tham khảo để AppUser

public sealed class Image : BaseEntity 
{ 
    public Image() 
    { 
     Products = new HashSet<Product>(); 
    } 

    public string Path { get; set; } 

    public AppUser AppUser { get; set; } // The Added Reference ... 

    public ICollection<Product> Products { get; set; } 
} 

Nếu tôi đặt "AppUser" bất động sản chuyển hướng bên trong lớp "Hình ảnh", các cơ sở dữ liệu được tạo ra sẽ có BỐN bảng mới khác so với NĂM mặc định của khung định danh.

Onion Database Problem with Identity Tables

tôi cần phải hợp nhất các bảng vào những cái mặc định. như thế nào?

EDIT:

Đây là mô hình nhận dạng mà nằm trong Lớp dữ liệu (mà tôi không thể tham khảo từ lõi).

public class ApplicationIdentityUser : 
    IdentityUser<int, ApplicationIdentityUserLogin, ApplicationIdentityUserRole, ApplicationIdentityUserClaim>, IDomainUser { 

    public ApplicationIdentityUser() 
     : base() { 
     Images = new HashSet<Image>(); 
    } 

    public string Name { get; set; } 
    public virtual ICollection<Image> Images { get; set; } 
} 


public class ApplicationIdentityRole : IdentityRole<int, ApplicationIdentityUserRole> 
{ 
    public ApplicationIdentityRole(){} 

    public ApplicationIdentityRole(string name){Name = name;} 
} 

public class ApplicationIdentityUserRole : IdentityUserRole<int> {} 

public class ApplicationIdentityUserClaim : IdentityUserClaim<int>{} 

public class ApplicationIdentityUserLogin : IdentityUserLogin<int>{} 

Ngoài ra đây là người xây dựng mô hình của tôi trong phương pháp OnModelCreating:

modelBuilder.Entity<Image>() 
      .Property(e => e.Id) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     modelBuilder.Entity<Image>() 
      .HasMany(e => e.Products) 
      .WithRequired(e => e.Image) 
      .WillCascadeOnDelete(false); 
     modelBuilder.Entity<ApplicationIdentityUser>() 
      .Property(e => e.Id) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     modelBuilder.Entity<ApplicationIdentityRole>() 
      .Property(e => e.Id) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     modelBuilder.Entity<ApplicationIdentityUserClaim>() 
      .Property(e => e.Id) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
+1

Bảng AspNet * dư thừa. Cần phải loại bỏ chúng. Kiểm tra ApplicationDbContext của bạn đang làm gì với những bảng này? – trailmax

+0

ApplicationDbContext của tôi là actully lái xe từ IdentityDbContext và tôi cần một cách để lưu trữ thông tin người dùng, bạn có nghĩa là tôi có thể sử dụng các bảng bắt đầu bằng Ứng dụng * không? –

+1

Tôi đang nói rằng chỉ nên có một bộ bảng * Người dùng, * UserClaims, v.v. Dường như cách bạn làm thừa kế trong ApplicationDbContext của bạn bị hỏng và bạn không ghi đè 'Users' và' Roles' và khác, vì vậy EF tạo 2 bộ bảng cho bạn. Kiểm tra điều đó. – trailmax

Trả lời

19

Được rồi tôi đã giải quyết điều này bằng cách làm như sau:

  1. Bao gồm một sự phụ thuộc vào cốt lõi của bạn để Microsoft. AspNet.Identity.Core
  2. Triển khai Giao diện IUser trên AppUser (giao diện này đến fr om Microsoft.AspNet.Identity.Core).
  3. Triển khai Giao diện IRole trên ApplicationRole.
  4. Hoàn toàn loại bỏ IdentityDbContext và chỉ kế thừa từ DbContext.
  5. Thực hiện phiên bản của riêng bạn IUserStore * cung cấp của bạn AppUser
  6. Thực hiện phiên bản của riêng bạn IRoleStore cung cấp của bạn ApplicationRole.

Tôi biết rằng làm cho một phụ thuộc vào Microsoft.AspNet.Identity.Core âm thanh Odd, nhưng chúng tôi chỉ cần IUser giao diện cơ bản được coi là Mô hình miền chính cho ứng dụng của bạn.

Ý tưởng cuối cùng ở đây là NHẬN ĐƯỢC RID OF THE Microsoft.AspNet.Identity.EntityFramework hoàn toàn.

Nhà phát triển quan tâm có thể +1 mục này, vì vậy tôi có thể tải lên mẫu làm việc đầy đủ trên GitHub.

+2

Tôi sắp bắt đầu cuộc hành trình này khi tôi đi đến kết luận tương tự rằng Microsoft.AspNet.Identity.EntityFramework là mã mẫu đẹp nhưng can thiệp vào miền của bạn nếu bạn định người dùng là mô hình miền lớp học đầu tiên. –

+2

có thể cung cấp liên kết đến giải pháp làm việc? – user1075940

+0

Thực sự muốn xem bạn đã loại bỏ IdentityDbContext như thế nào và cách bạn tham chiếu ApplicationIdentityUser của bạn trong thực thể Hình ảnh như nó nằm trong Core chứ không phải lớp dữ liệu! Bất kỳ ví dụ nào sẽ được đánh giá cao. – webStuff

1

Tôi đang sử dụng khung này, không cần phải có liên kết trong mọi thực thể Để nhận tham chiếu userID, tôi đã thêm thuộc tính UserIDBy vào BaseEntity để mọi thực thể sẽ kế thừa nó.

public abstract class BaseEntity 
{ 
    public int Id { get; set; } 
    public string UserIDBy { get; set; } 
} 

Tiếp theo, trong dự án web, đã có một phương pháp mở rộng gọi là GetUserId(this IIdentity identity) trong IdentityExtensions.cs, vì vậy dự trữ các UserIDBy trong mọi kết quả Tạo và chỉnh sửa hành động:

Tạo Action Result:

// POST: /Region/Create 
    [HttpPost] 
    public async Task<ActionResult> Create([Bind(Include = "RegionName")] Region region) 
    { 
     if (ModelState.IsValid) 
     { 
      // TODO: Add insert logic here 
      var id = User.Identity.GetUserId(); 
      region.UserIDBy = id.ToString(); 

      await _regionService.AddAsync(region); 
      return Json(new { success = true }); 
     } 

     return PartialView("_Create", region); 
    } 

Sửa Action Result:

//// POST: /Region/Edit/5 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit([Bind(Include = "id,RegionName")] Region region) 
    { 
     if (ModelState.IsValid) 
     { 
      var id = User.Identity.GetUserId(); 
      region.UserIDBy = id.ToString(); 
      _regionService.Update(region); 
      return Json(new { success = true }); 
     } 
     return PartialView("_Edit", region); 
    } 

Dont quên import nó:

using Myapp.Web.Extensions; 
+0

Rất thông minh. Cám ơn vì đã chia sẻ. ASPNETIdentityWithOnion là một trình bao tuyệt vời, nhưng nhức đầu của việc tạo mối quan hệ với các bảng tùy chỉnh và khung định danh không đáng giá. – JoshYates1980

+0

Bạn có một dự án nguồn mở thực hiện ASPNETIdentityWithOnion không? – JoshYates1980

0

Chỉ cần stumbled khi này, có cùng một vấn đề.

Sự cố với câu trả lời được đánh dấu là nó vẫn tham chiếu Microsoft.AspNet, điều này làm cho nó trở nên thô ráp đối với các kế hoạch .NET Core trong tương lai.

Vấn đề chính là thực sự với nỗ lực chung để xây dựng trong một tính năng xác thực trong lõi, mà đánh bại mục đích.

Cân nhắc cho phép chức năng tích hợp để xác thực và ủy quyền web vẫn còn trong lớp web và tham chiếu đối tượng người dùng cốt lõi (UserProfile?) Đại diện cho nhu cầu cốt lõi. Điều này cũng sẽ đơn giản hóa việc chuyển sang phương thức xác thực khác (AD).

Tùy thuộc vào sở thích của bạn, bạn có thể tham khảo Core.UserProfile từ AspNetUser của bạn để tránh nhiều cuộc gọi SQL hoặc chỉ cần đảm bảo có chính sách bộ nhớ cache tốt trên các hoạt động Core.UserProfile.

Điều này cho phép bạn kiểm soát các phương thức xác thực riêng biệt với mô hình cốt lõi của mình.

Các vấn đề liên quan