2010-01-07 28 views
5

Tôi có một lớp cơ sở với một thuộc tính và tôi muốn ẩn nó trong một lớp dẫn xuất. Có cách nào để làm điều này khác hơn là sử dụng sự phản ánh?C# ẩn Thuộc tính trong nguồn gốc Lớp

[Authorize(Roles = "User,Admin,Customs")] 
public abstract class ApplicationController : Controller 
{ 
} 

// hide the Authorize attribute 
public class ErrorController : ApplicationController 
{ 
} 
+0

Vì một lý do nào đó, tôi nhầm lẫn về điều này Q. –

+0

Nếu đây là về MVC, vui lòng gắn thẻ nó như vậy. –

+0

Giống như không thể nhìn thấy với sự phản ánh rằng lớp cơ sở được trang trí với thuộc tính đó? –

Trả lời

2

Bạn có thể ghi đè lên AuthorizeAttribute bằng lớp của riêng bạn và chỉ định nó không được kế thừa.

[AttributeUsage(AttributeTargets.Class, Inherited=false)] 
public class NonInheritedAuthorizeAttribute : AuthorizeAttribute 
{ 
    // Constructors, etc. 
} 

Bây giờ bạn có thể chỉ định lớp nào sẽ sử dụng, miễn là bạn sở hữu ApplicationController.

+0

Tôi cũng nghĩ về việc này, nhưng tôi cố gắng sử dụng các lớp của Microsoft bất cứ khi nào có thể vì vậy tôi đã chọn chỉ loại bỏ thuộc tính Authorize khỏi lớp cơ sở của tôi và thêm nó vào mỗi bộ điều khiển có nguồn gốc. – PaulN

+0

+1 cho 'Thừa kế = false', không phải về MVC nhưng đảm bảo rằng lớp/phương thức dẫn xuất không cố gắng sửa đổi thuộc tính thuộc tính. – CallMeLaNN

1

Phụ thuộc vào ý nghĩa của từ 'Ẩn'. Bạn sẽ có thể thu hồi giấy phép như thế này:

// hide the Authorize attribute 
[Authorize(Roles = "")] 
public class ErrorController : ApplicationController 
{ 
} 
+1

Đây chính xác là những gì tôi muốn làm (cho phép một người không được ủy quyền xem Chế độ xem). Thật không may, AuthorizeAttribute đầu tiên kiểm tra nếu (! User.Identity.IsAuthenticated) sau đó nó xác nhận các vai trò. Vì vậy, đó là lý do tại sao tôi muốn "ẩn" hoặc loại bỏ các thuộc tính từ lớp cơ sở chỉ cho lớp ErrorController. – PaulN

+2

Có lẽ bạn nên xem xét lại thiết kế thừa kế: Phát minh một lớp cơ sở mới và lấy được cả hai bộ điều khiển từ đó. –

2

Nếu đó là một phương pháp/prop, bạn có thể tái khai báo (new) các thành viên mà không có thuộc tính vi phạm. Tôi không biết cách nào với các thuộc tính cấp lớp.

public new SomeType Foo() { return base.Foo(); } 
0

Bạn có thể chỉ định các thuộc tính 'AttributeUage' trên lớp Thuộc tính của bạn, như thế này:

[AttributeUsage(AttributeTargets.Class, Inherited=false)] 
public class AuthorizeAttribute : Attribute 
{ 
} 

Sau đó, các lớp học có nguồn gốc từ các lớp học, nơi bạn đã áp dụng các thuộc tính, sẽ không thừa hưởng thuộc tính.

Ow, bây giờ tôi nhận ra rằng thuộc tính Ủy quyền không phải là thuộc tính tùy chỉnh.

+0

Có, đây là một lớp được tạo bởi nhóm Microsoft trong System.Web.MVC. – PaulN

3

Xóa các đối tượng được kế thừa từ lớp cơ sở vi phạm Liskov Substitution Principle. Phá vỡ di sản theo cách này thường xé đầu xấu xí của nó với hậu quả không mong muốn và bất ngờ — sau khi quá muộn để thay đổi vấn đề gốc.

Vì vậy, ngay cả khi có cách nào, tôi sẽ trả lời rằng bạn không nên sử dụng phần lớn thời gian. Các lựa chọn thay thế cho thừa kế có thể áp dụng, chẳng hạn như ngăn chặn (có- thay vì số của kế thừa là-) hoặc tái cấu trúc cơ sở thành giao diện riêng biệt mà cả hai có thể triển khai; hoặc thậm chí kết hợp cả hai.

+0

Vâng, nó sẽ được tốt đẹp để thiết lập một ủy quyền mặc định cho trang web bằng cách sử dụng lớp cơ sở. Tôi chỉ có 1 bộ điều khiển trong số 9 mà chỉ cho phép quản trị viên. Vì dường như không thể loại bỏ thuộc tính lớp cơ sở thì đây là lời khuyên tốt nhất.Tôi đã xóa [Ủy quyền (Vai trò = "Người dùng, Quản trị, Hải quan")] và tôi sẽ chỉ đặt nó trong mọi bộ điều khiển. – PaulN

+0

Thuộc tính không giống như các thành viên lớp học, và không nhất thiết phải thừa hưởng (đó là lý do tại sao có 'AttributeUsage (Inherited = false)'). Vì vậy, LSP không nhất thiết phải áp dụng ở đây. –

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