【问题标题】:Check if instance of class is annotated with attribute检查类的实例是否用属性注释
【发布时间】:2013-09-27 15:02:59
【问题描述】:

我有一个类(应用程序),它具有另一个自定义类(就业)类型的多个属性。我想根据 Application 类的属性是否标有 [Required] 有条件地验证就业类。

根据我的发现,我认为我应该使用 IValidatableObject 接口进行就业。问题是我不确定如何使用反射(或其他方法)来检查该类的实例是否用 [Required] 属性注释以确定是否验证它。

也许这根本不可能。我最初为就业类设置了两个类:Employment 和EmploymentRequired。只有后者在其属性上具有验证属性。它有效,但如果可能的话,我想只使用一个类。

public class Application
{
  [Required]
  public Employment Employer1 { get; set; }
  public Employment Employer2 { get; set; }
}

public class Employment : IValidatableObject
{
  [Required]
  public string EmployerName { get; set; }
  [Required]
  public string JobTitle { get; set; }
  public string Phone { get; set; }

  public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
  {
    var results = new List<ValidationResult>();
    var t = this.GetType();
    //var pi = t.GetProperty("Id");
    //var isRequired = Attribute.IsDefined(pi, typeof(RequiredAttribute));
    //how can I get the attributes of this property in Application class?
    if (isRequired)
    {
        Validator.TryValidateProperty(this.EmployerName,
            new ValidationContext(this, null, null) { MemberName = "EmployerName" }, results);
        Validator.TryValidateProperty(this.JobTitle,
            new ValidationContext(this, null, null) { MemberName = "JobTitle" }, results);
    }
    return results;
  }
}

【问题讨论】:

  • 您需要参考在就业类中包含应用程序类。通过使用反射,您可以检查此 emplyment 的实例是否与应用程序类实例的属性 employee1 / 2 匹配,如果该属性已设置 [required] attr,则验证就业类实例
  • Check if property has attribute 的可能重复项
  • @rt2800 我没有完全关注你。你能分享一些代码(甚至是伪代码)来解释更多吗?
  • @PrestonGuillot 我从示例中的那个问题中获取了一些代码,但我不确定如何在此处应用它。我以前检索过类似属性的属性,但只是在嵌套在另一个类中时没有。

标签: c# .net validation reflection data-annotations


【解决方案1】:

您应该能够使用 Attribute.IsDefined 检查所需的属性。

http://msdn.microsoft.com/en-us/library/system.attribute.isdefined.aspx

【讨论】:

  • 如何从 Validate 就业方法中检查 Application 中的 [Required] 属性?
【解决方案2】:

似乎您不能这样做,因为使用反射您无法获得引用当前实例的父对象/类,更何况引用属性信息。

编辑:也许您可以使用必需和非必需的验证模式使就业类型通用?

【讨论】:

    【解决方案3】:

    我认为您正在搜索 Attribute.IsDefined 方法。您必须首先获取对字段本身的引用,然后验证属性的存在。如下所示(改编自 MSDN 的示例):

    // Get the class type (you can also get it directly from an instance)
    Type clsType = typeof(Application);
    
    // Get the FieldInfo object
    FieldInfo fInfo = clsType.GetField("Employer1");
    
    // See if the Required attribute is defined for the field 
    bool isRequired = Attribute.IsDefined(fInfo , typeof(RequiredAttribute));
    

    【讨论】:

    • 但是我如何确定某个就业实例是否适用于属性 Employer1?
    • 如果您有对容器应用程序对象的引用(假设是 app),那么您可以简单地测试 app.Employer1 == 您的实例。
    • 我正在尝试在 Validate 就业方法中执行此操作,该方法似乎没有引用 Application。除非您知道一种方法,否则我可以在该方法中获取对父容器的引用。
    • 我想您可以使用一些非常复杂的代码来扫描您的内存以查找对您的雇主的引用,从而找到应用程序引用。但是,将 Application 实例显式传递或通过在 Employer1 中包含对 Application 类的反向引用似乎是更好的编码实践。毕竟,您要求的信息并不是真正有关就业实例或类的信息,而是有关应用程序的信息。
    • 另外,您还可以在“就业”上插入一个新的布尔字段,说明是否需要,然后在 Application 类的初始化中设置该字段的值(您可以在其中使用 Attribute.已定义)。
    【解决方案4】:

    由于我正在尝试做的事情似乎不太可能,我根据@user1578874 的建议找到了一种不同的方法。我向就业添加了一个 IsRequired 属性,并使用 MVC Foolproof Validation 将这些属性标记为 [RequiredIf("IsRequired")]。似乎是最干净的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多