2010-05-19 39 views
14

Tôi muốn tạo ra một thuộc tính tùy chỉnh mà có thể được sử dụng trên một tài sản như:Cách nhận và sửa đổi giá trị thuộc tính thông qua Thuộc tính tùy chỉnh?

[TrimInputString] 
public string FirstName { get; set; } 

đó sẽ là chức năng tương đương với

private string _firstName 
public string FirstName { 
    set { 
    _firstName = value.Trim(); 
    } 
    get { 
    return _firstName; 
    } 
} 

Vì vậy, về cơ bản tất cả các bất động sản thời gian được thiết lập giá trị này sẽ được tỉa .

Làm cách nào để nhận giá trị được phân tích cú pháp, sửa đổi giá trị đó và sau đó đặt thuộc tính với giá trị mới tất cả từ bên trong thuộc tính?

[AttributeUsage(AttributeTargets.Property)] 
public class TrimInputAttribute : Attribute { 

    public TrimInputAttribute() { 
    //not sure how to get and modify the property here 
    } 

} 
+0

Tôi nghĩ rằng một cách tiếp cận tốt hơn là một DataBinder: http://stackoverflow.com/a/1734025/7720 – Romias

Trả lời

6

Đó không phải là cách các thuộc tính hoạt động. Bạn không thể truy cập bất cứ thuộc tính nào được gắn vào từ bên trong hàm tạo.

Nếu bạn muốn thực hiện công việc này, bạn sẽ cần phải thực hiện một số loại lớp bộ vi xử lý mà bạn vượt qua đối tượng, sau đó đi qua các trường và thực hiện điều gì đó tùy thuộc vào các thuộc tính. Các hoạt động để làm có thể được xác định trong thuộc tính (một thuộc tính cơ sở trừu tượng là tiện dụng ở đây), nhưng bạn vẫn sẽ cần phải đi qua các lĩnh vực bằng tay để áp dụng các hoạt động.

1

Như Matti đã chỉ ra, đây không phải là cách các thuộc tính hoạt động. Tuy nhiên, bạn có thể sử dụng PostSharp AOP framework để thực hiện việc này, có thể ghi đè OnMethodBoundaryAspect. Nhưng đây không phải là tầm thường.

7

iam làm điều này, không phải là cách rất thuyết phục nhưng làm việc của nó

lớp bản demo

public class User 
{ 

[TitleCase] 
public string FirstName { get; set; } 

[TitleCase] 
public string LastName { get; set; } 

[UpperCase] 
public string Salutation { get; set; } 

[LowerCase] 
public string Email { get; set; } 

} 

Viết Thuộc tính cho chữ thường, những người khác có thể được viết theo cách thức tương tự

public class LowerCaseAttribute : ValidationAttribute 
{ 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     //try to modify text 
      try 
      { 
       validationContext 
       .ObjectType 
       .GetProperty(validationContext.MemberName) 
       .SetValue(validationContext.ObjectInstance, value.ToString().ToLower(), null); 
      } 
      catch (System.Exception) 
      {          
      } 

     //return null to make sure this attribute never say iam invalid 
     return null; 
    } 
} 

Cách không thanh lịch như thuộc tính xác thực thực sự của nó b ut it works

+0

Điều này, tất nhiên, chỉ hoạt động nếu chương trình của bạn tại một số điểm chạy xác nhận trên các đối tượng. Thú vị hack, nhưng tôi sẽ không sử dụng nó trong mã sản xuất. –

+1

Có thể bạn muốn 'return ValidationResult.Success;' – Nikola

0

Điều này có thể được thực hiện với Dado.ComponentModel.Mutations.

public class User 
{ 
    [Trim] 
    public string FirstName { get; set; } 
} 

// Then to preform mutation 
var user = new User() { 
    FirstName = " David Glenn " 
} 

new MutationContext<User>(user).Mutate(); 

Bạn có thể xem thêm tài liệu here.

+0

Không phán xét về chính giải pháp đó. Nhưng không gian tên đã chọn tôi thấy gây hiểu lầm. Ấn tượng đầu tiên của tôi là nó là một phần của bản thân .Net framework. Trong khi nó không phải là. Tại sao không bắt đầu không gian tên với RoyDukkey.ComponentModel.Mutations và cung cấp tín dụng cho tên của bạn. –

+0

Tôi đồng ý. Điều này ban đầu được xây dựng như một đề xuất, nhưng từ đó đã bị đóng cửa. Tôi chưa có thời gian để thay đổi không gian tên thành một cái gì đó thích hợp hơn. – roydukkey

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