简体   繁体   English

我如何使我的财产验证生效?

[英]How can I get my Property Validation to work?

I'm trying to create some parameter attributes, but they are not running. 我正在尝试创建一些参数属性,但是它们没有运行。

Here's some sample code of the attribute: 这是该属性的一些示例代码:

public abstract class ArgumentValidationAttribute : Attribute
{
    public abstract void Validate(object value, string argumentName);
}

[AttributeUsage(AttributeTargets.Parameter)]
public class NotNullAttribute : ArgumentValidationAttribute
{
    public override void Validate(object value, string argumentName)
    {
        if (value == null)
        {
            throw new ArgumentNullException(argumentName);
        }
    }
}

and its usage: 及其用法:

public async Task Deactivate(int id, [NotNull][MaxLength(25)] string modifiedBy)
{
    // do something
}

However, when I call Deactivate(5, null) the attribute does not fire. 但是,当我调用Deactivate(5, null)该属性不会触发。 I've put breakpoints in my calling method and the attribute itself, but the breakpoint in the attribute never hits. 我已经在我的调用方法和属性本身中设置了断点,但是该属性中的断点从未命中。

How do I get the attribute to call the Validate method? 如何获取属性以调用Validate方法?

What you are trying to achieve, makes sense. 您想要实现的目标是有道理的。 However, how you are trying to achieve will not work, at least the way you intend it to. 但是,您试图实现的目标将无法正常运行,至少不会达到您的预期目标。 Remember attributes adds info to the metadata and NOT to the method itself. 记住属性将信息添加到元数据,而不是方法本身。 I'll demonstrate with a basic example of how attributes work. 我将通过一个基本示例演示属性的工作原理。

For the sake of this example, I have simplified your NotNullAttribute to directly derive from Attribute - 为了这个例子,我简化了您的NotNullAttribute以直接从Attribute派生-

[AttributeUsage(AttributeTargets.Parameter)]
public class NotNullAttribute : Attribute
{
    public void Validate(object value, string argumentName)
    {
        if (value == null)
        {
            throw new ArgumentNullException(argumentName);
        }
    }
}

Now consider this TestClass which is partial and have your Deactivate method - 现在考虑一下这个TestClass ,它是partial并具有您的Deactivate方法-

public partial class TestClass
{
    public void Deactivate(int id, [NotNull] string modifiedBy)
    {
        // do something
    }
}

Second part of the partial TestClass is as follows - partial TestClass第二部分如下-

public partial class TestClass
{
    public void CallDeactivate(int id, string modifiedBy)
    {
        var classType = typeof(TestClass);
        var deactivateMethod = classType.GetMethod("Deactivate");
        var parameterModifiedBy = deactivateMethod.GetParameters()[1];
        var notNullAttribute = parameterModifiedBy.CustomAttributes.FirstOrDefault();
        if (notNullAttribute.AttributeType == typeof(NotNullAttribute))
        {
            var attrObj = Activator.CreateInstance<NotNullAttribute>();
            attrObj.Validate(modifiedBy, parameterModifiedBy.Name);

            this.Deactivate(id, modifiedBy);
        }
    }
}

Now you don't call Deactivate directly instead you call 'CallDeactivate' - 现在,您不直接调用Deactivate ,而是调用“ CallDeactivate”-

var testClass = new TestClass();
testClass.CallDeactivate(12, null);

This will work and will throw ArgumentNullException . 这将起作用并且将抛出ArgumentNullException What CallDeactivate function do is read metadata of Deactivate function parameters and execute any functionality you want your attribute to define. CallDeactivate函数的作用是读取Deactivate函数参数的元数据,并执行您希望属性定义的任何功能。 Similar approach is used by EntityFramework to execute Data Contract attributes. EntityFramework使用类似的方法来执行数据协定属性。

Hope this answers your question. 希望这能回答您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM