【问题标题】:How do C# derived Attributes work internally?When are the methods inside it called to act upon the class/method/property on which they are declared?C# 派生属性如何在内部工作?它内部的方法何时调用以作用于声明它们的类/方法/属性?
【发布时间】:2019-06-02 17:49:21
【问题描述】:

我正在编写 MVC 代码,我在模型上使用了 ValidationAttributes,例如 -RequiredAttribute、RangeAttribute 等。我只是不明白这些在内部是如何工作的。我有一个从 ValidationAttribute 派生的 CustomAttribute ,其中 IsValid 被覆盖并进行了一些自定义检查。当我在 CustomAttribute 上放置断点时,它在更新模型时被调用,这是有道理的。但是我不明白对象在哪里传递给属性。如何以及为什么调用方法。

1.在 Visual Studio 中,我不断检查属性的定义,似乎缺少一些东西。应用属性的对象如何传递给属性类/对象(属性对象是否已实例化?) 2.我进入我的目录 - C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7 并将 System.ComponentModel.DataAnnotations.dll 拖到 ju​​stdecompile 窗口中。我根本看不到任何实现。 IsValid 有一个空白正文。

namespace System.ComponentModel.DataAnnotations
{
    //
    // Summary:
    //     Specifies that a data field value is required.
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
    public class RequiredAttribute : ValidationAttribute
    {
        //
        // Summary:
        //     Initializes a new instance of the System.ComponentModel.DataAnnotations.RequiredAttribute
        //     class.
        public RequiredAttribute();

        //
        // Summary:
        //     Gets or sets a value that indicates whether an empty string is allowed.
        //
        // Returns:
        //     true if an empty string is allowed; otherwise, false. The default value is false.
        public bool AllowEmptyStrings { get; set; }

        //
        // Summary:
        //     Checks that the value of the required data field is not empty.
        //
        // Parameters:
        //   value:
        //     The data field value to validate.
        //
        // Returns:
        //     true if validation is successful; otherwise, false.
        //
        // Exceptions:
        //   T:System.ComponentModel.DataAnnotations.ValidationException:
        //     The data field value was null.
        public override bool IsValid(object value);
    }
}

以上内容来自在必需属性上按 F12 时的元数据。这里 IsValid 有一个 value 参数。但是没有代码显示它的调用或参数被传递到哪里。

我希望看到的答案是一个示例代码,其中可能会在方法/属性(如适用)上应用必需/范围/条件属性,然后逐步了解属性何时实际工作或它是否不是属性,那么工作在哪里完成。

【问题讨论】:

  • 在进一步检查中,我将 mscorlib.dll 拖入 JustDecompile 并看到了必需属性的 IsValid 方法 - [__DynamicallyInvokable] public override bool IsValid(object value) { if (value == null) { return错误的; } 字符串 str = 值作为字符串; if (str == null || this.AllowEmptyStrings) { return true; } 返回 str.Trim().Length != 0; } 。它仍然没有回答给我答案。

标签: c# .net attributes custom-attributes


【解决方案1】:

框架自动调用 IsValid 方法。 它使用反射在您指定的类中搜索从 ValidationAttribute 派生的所有属性,并调用它们的 IsValid 方法。

但这是一个特例。如果您创建一个直接从 Attribute 派生的自定义属性,您必须自己调用它。

如果你喜欢,可以在 ASP.NET 的源代码中搜索确切的工作流:https://github.com/aspnet/AspNetWebStack

【讨论】:

  • 但我虽然Required 属性与ASP.NET 无关。它甚至可以应用于控制台应用程序中的类属性,对吗?条件属性怎么样?它是如何自动工作的?
  • 是的,您可以将属性应用到任何地方的类属性上,但除非您使用的框架知道它,否则它不会自动调用。您可以将 ValidationAttribute 视为必须集成到框架中才能自动工作的一般原则。
  • 而 ConditionalAttribute 有点不同。编译器在编译时检查条件属性。见:docs.microsoft.com/de-de/dotnet/api/…
  • 我可以在它集成到框架中的某个地方看到源代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 2018-02-15
  • 2023-03-13
  • 1970-01-01
  • 2023-03-22
  • 2021-11-08
相关资源
最近更新 更多