2011-11-25 21 views
10

Mặc dù thực tế là tôi đã ở đây một thời gian, đây là câu hỏi đầu tiên của tôi về SO, vì vậy hãy nhẹ nhàng với tôi.Đây có phải là Hiệu trưởng Tùy chỉnh trong Bộ điều khiển Cơ sở ASP.NET MVC 3 khủng khiếp không hiệu quả?

Tôi đang sử dụng ASP.NET MVC 3 và tôi muốn tạo Principal tùy chỉnh để tôi có thể lưu thêm một chút thông tin về người dùng hiện tại so với tiêu chuẩn, do đó không phải truy cập cơ sở dữ liệu quá thường xuyên. Đó là những thứ khá chuẩn mà tôi đang theo đuổi. Hãy chỉ nói địa chỉ email và id người dùng trong ví dụ đầu tiên.

Tôi đã quyết định lưu trữ đối tượng trong bộ nhớ cache vì tôi biết rằng không nên lưu trữ nó trong phiên.

Tôi cũng không muốn tiếp tục truyền đối tượng User, vì vậy tôi muốn ghi đè đối tượng User trong bộ điều khiển. Vì vậy, tôi chỉ có thể đi User.UserId và được đảm bảo về điều gì đó.

Vì vậy, tôi đã tạo ra một hiệu trưởng tùy chỉnh như thế này:

public class MyPrincipal : IPrincipal 
{ 
    public MyPrincipal(IIdentity ident, List<string> roles, string email, Guid userId) 
    { 
     this._identity = ident; 
     this._roles = roles; 
     this._email = email; 
     this._userId = userId; 
    } 

    IIdentity _identity; 

    public IIdentity Identity 
    { 
     get { return _identity; } 
    } 

    private List<string> _roles; 

    public bool IsInRole(string role) 
    { 
     return _roles.Contains(role); 
    } 

    private string _email; 

    public string Email 
    { 
     get { return _email; } 
    } 

    private Guid _userId; 

    public Guid UserId 
    { 
     get { return _userId; } 
    } 
} 

Và tôi có một bộ điều khiển cơ sở như thế này:

public class BaseController : Controller 
    { 
     protected virtual new MyPrincipal User 
     { 
      get 
      { 
       if (base.User is MyPrincipal) 
       { 
        return base.User as MyPrincipal; 
       } 
       else 
       { 
        return new MyPrincipal(base.User.Identity, new List<string>(0), "", Guid.Empty); 
       } 
      } 
     } 

     protected override void OnAuthorization(AuthorizationContext filterContext) 
     { 
      if (User != null) 
      { 
       if (User.Identity.IsAuthenticated) 
       { 
        if (User.Identity is FormsIdentity) 
        { 
         FormsIdentity id = base.User.Identity as FormsIdentity; 
         MyPrincipal principal = (MyPrincipal)filterContext.HttpContext.Cache.Get(id.Name); 
         if (principal == null) 
         { 
          MembershipUser user = Membership.GetUser(); 

          // Create and populate your Principal object with the needed data and Roles. 
          principal = new MyPrincipal(id, Roles.GetRolesForUser(id.Name).ToList(), user.Email, (Guid)user.ProviderUserKey); 
          filterContext.HttpContext.Cache.Add(
          id.Name, 
          principal, 
          null, 
          System.Web.Caching.Cache.NoAbsoluteExpiration, 
          new System.TimeSpan(0, 30, 0), 
          System.Web.Caching.CacheItemPriority.Default, 
          null); 
         } 
         filterContext.HttpContext.User = principal; 
         System.Threading.Thread.CurrentPrincipal = principal; 
         base.OnAuthorization(filterContext); 
        } 
       } 
      } 
     } 
    } 

Nếu bạn có một cái nhìn, bạn sẽ nhanh chóng nhận ra rằng nếu người dùng có chưa đăng nhập thì mọi cuộc gọi gọi tới đối tượng User sẽ phải chạy qua bit mã này:

return new MyPrincipal(base.User.Identity, new List<string>(0), "", Guid.Empty); 

và điều này cảm thấy không hiệu quả khủng khiếp đối với tôi, mặc dù nó chỉ tạo ra các đối tượng trống cho những thứ còn thiếu.

Nó hoạt động tốt. Vì vậy, tôi đoán tôi muốn biết nếu điều này là thực sự okay và tôi nên ngừng được như vậy hậu môn về hiệu suất và hiệu quả, hoặc nếu nỗi sợ của tôi là chính xác, trong trường hợp những gì tôi nên làm gì để thay thế? Tôi có thể không? [Xin đừng nói "Bắt một cuộc sống, bạn đời!"]

+4

Đừng quên [Knuth] (http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize) ... "Premature tối ưu hóa là gốc rễ của mọi tội lỗi." Đó là để nói, có bạn thực sự thấy vấn đề hiệu suất? –

+0

+1 Đẹp nhất. Không, tôi không có.Nhưng vấn đề là tôi cảm thấy khá thông minh khi làm cho nó hoạt động cho đến khi tôi nhìn vào dòng mã khó chịu đó! Wow! Tôi thực sự là hậu môn! Tôi đoán đó là những gì xuất phát từ việc bắt đầu viết mã trên BBC Micro, nơi các chu kỳ đồng hồ rất ít và xa ... –

Trả lời

6

Không - không có gì đặc biệt sai với mã này từ một điểm đứng hiệu suất nổi bật. PLENTY của các đối tượng đang tạo ra ở mặt sau trong ASP.NET, đối tượng duy nhất của bạn là một giọt trong thùng. Kể từ khi instantiation lớp là cực kỳ nhanh chóng tôi sẽ không được quan tâm về nó.

Tại sao bạn bỏ qua các phiên ở đây? Thông tin phiên không có ngày hết hạn, do đó không có kiểm tra thêm nào sau hậu trường. Trừ khi bạn đang sử dụng một máy chủ phiên proc, không có serialization của đối tượng của bạn (không có bộ nhớ cache hoặc là). Bộ nhớ cache dành cho mọi người dùng - vì vậy bạn phải có cơ hội (dù nhẹ) một lỗi mã trả về sai chính khi bộ nhớ cache cho mỗi người dùng - không chạy rủi ro đó.

Nếu bạn muốn điều này có sẵn cho tất cả các yêu cầu đó (không chỉ MVC dựa) Tôi sẽ xem xét việc thiết này trong Application_PostAuthenticateRequest

+0

+1 Cảm ơn Adam. Khác với việc xem xét an ninh không có lý do cụ thể tôi bỏ qua phiên. Tôi cố tình không bao gồm nó trong 'Application_PostAuthenticateRequest' như tôi nghĩ rằng mã trong đó sẽ được chạy cho các yêu cầu của những thứ như css, hình ảnh, javascript, vv trong khi với mã của tôi nó sẽ không. Có đúng không? Bất kỳ hình ảnh nào cần được bảo vệ đều được phục vụ bởi các phương thức MVC 'FileContentResult' và do đó vẫn được bảo vệ. –

2

bài này có thể được sử dụng. Lưu ý việc sử dụng userdata trong vé xác thực.

ASP.NET MVC - Set custom IIdentity or IPrincipal

+0

Cảm ơn vì điều này. Tôi đã biết về việc sử dụng vé xác thực biểu mẫu nhưng tôi muốn làm điều đó mà không cần sử dụng cookie, trừ khi bạn đề xuất tôi lưu trữ nó ở một nơi khác. –

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