如何通过自定义属性获取和修改属性值?

时间:2022-11-26 23:25:34

I want to create a custom attribute that can be used on a property like:

我想创建一个可以在以下属性上使用的自定义属性:

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

that will be functional equivalent of

这将是功能相当于

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

So basically every time property is set the value will be trimmed.

所以基本上每次设置属性时都会修剪该值。

How do I get the value parsed, modify that value and then set the property with the new value all from within the attribute?

如何获取解析的值,修改该值,然后使用属性中的新值all设置属性?

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

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

}

4 个解决方案

#1


6  

That's not how attributes work. You can't access whatever the attribute is attached to from within the constructor.

这不是属性的工作方式。您无法从构造函数中访问附加属性的任何内容。

If you want to make this work, you'll need to make some kind of processor class to which you pass the object, which then goes through the fields and does something depending on the attributes. The operation to do may be defined within the attribute (an abstract base attribute is handy here), but you'll still need to go through the fields by hand to apply the operation.

如果你想使这个工作,你需要制作一些传递对象的处理器类,然后通过字段并根据属性做一些事情。可以在属性中定义要执行的操作(这里抽象的基本属性很方便),但是您仍然需要手动遍历字段以应用操作。

#2


7  

iam doing this , not very convincing way but its working

我这样做,不是很有说服力的方式,但它的工作

demo class

演示课

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; }

}

Writing Attribute for LowerCase, others can be written in the similar manner

为LowerCase编写属性,其他可以用类似的方式编写

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;
    }
}

Not very elegant way as its actually implementing Validation attribute but it works

不是很优雅的方式,因为它实际上实现Validation属性,但它的工作原理

#3


1  

As Matti pointed out, this is not how attributes work. However, you could use the PostSharp AOP framework to accomplish this, probably overriding OnMethodBoundaryAspect. But this is not trivial.

正如马蒂指出的那样,这不是属性如何运作的。但是,您可以使用PostSharp AOP框架来完成此任务,可能会覆盖OnMethodBoundaryAspect。但这不是微不足道的。

#4


0  

This can be done with Dado.ComponentModel.Mutations.

这可以使用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();

You can see more documentation here.

您可以在此处查看更多文档。

#1


6  

That's not how attributes work. You can't access whatever the attribute is attached to from within the constructor.

这不是属性的工作方式。您无法从构造函数中访问附加属性的任何内容。

If you want to make this work, you'll need to make some kind of processor class to which you pass the object, which then goes through the fields and does something depending on the attributes. The operation to do may be defined within the attribute (an abstract base attribute is handy here), but you'll still need to go through the fields by hand to apply the operation.

如果你想使这个工作,你需要制作一些传递对象的处理器类,然后通过字段并根据属性做一些事情。可以在属性中定义要执行的操作(这里抽象的基本属性很方便),但是您仍然需要手动遍历字段以应用操作。

#2


7  

iam doing this , not very convincing way but its working

我这样做,不是很有说服力的方式,但它的工作

demo class

演示课

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; }

}

Writing Attribute for LowerCase, others can be written in the similar manner

为LowerCase编写属性,其他可以用类似的方式编写

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;
    }
}

Not very elegant way as its actually implementing Validation attribute but it works

不是很优雅的方式,因为它实际上实现Validation属性,但它的工作原理

#3


1  

As Matti pointed out, this is not how attributes work. However, you could use the PostSharp AOP framework to accomplish this, probably overriding OnMethodBoundaryAspect. But this is not trivial.

正如马蒂指出的那样,这不是属性如何运作的。但是,您可以使用PostSharp AOP框架来完成此任务,可能会覆盖OnMethodBoundaryAspect。但这不是微不足道的。

#4


0  

This can be done with Dado.ComponentModel.Mutations.

这可以使用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();

You can see more documentation here.

您可以在此处查看更多文档。