【问题标题】:How to get and modify a property value through a custom Attribute?如何通过自定义 Attribute 获取和修改属性值?
【发布时间】:2010-05-19 09:41:40
【问题描述】:

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

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

这将在功能上等同于

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

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

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

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

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

}

【问题讨论】:

标签: c# asp.net-mvc


【解决方案1】:

我正在这样做,不是很有说服力,但它的工作原理

演示课

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

}

为小写写属性,其他类似写法

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

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

【讨论】:

  • 当然,这仅在您的程序在某些时候对对象运行验证时才有效。有趣的 hack,但我不会在生产代码中使用它。
  • 也许你想return ValidationResult.Success;
【解决方案2】:

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

如果你想完成这项工作,你需要创建某种处理器类,将对象传递给该处理器类,然后通过字段并根据属性执行某些操作。可以在属性中定义要执行的操作(抽象的基本属性在这里很方便),但您仍然需要手动遍历字段来应用操作。

【讨论】:

    【解决方案3】:

    正如 Matti 指出的,这不是属性的工作方式。但是,您可以使用PostSharp AOP framework 来完成此操作,可能会覆盖 OnMethodBoundaryAspect。但这并非小事。

    【讨论】:

      【解决方案4】:

      这可以通过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();
      

      您可以查看更多文档here

      【讨论】:

      • 不判断解决方案本身。但是我发现选择的命名空间具有误导性。我的第一印象是它是 .Net 框架本身的一部分。虽然不是。为什么不以 RoyDukkey.ComponentModel.Mutations 开始命名空间,并将您的名字也归功于您。
      • 我同意。这最初是作为一项提议而建造的,但后来被关闭了。我还没有时间将命名空间更改为更合适的名称。
      【解决方案5】:

      我遇到了这个问题 你应该使用 JsonSeralizer 属性 它会起作用的

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-07
      • 2013-04-16
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      相关资源
      最近更新 更多