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

时间:2019-07-18 00:27:49

标签: c#

我正在尝试创建一些参数属性,但是它们没有运行。

以下是该属性的一些示例代码:

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

及其用法:

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

但是,当我调用Deactivate(5, null)时,该属性不会触发。我已经在我的调用方法和属性本身中添加了断点,但是该属性中的断点从未命中。

如何获取用于调用Validate方法的属性?

1 个答案:

答案 0 :(得分:0)

您要实现的目标很有意义。但是,您试图实现的目标将无法正常运行,至少不会达到您的预期目标。记住属性将信息添加到元数据,而不是方法本身。我将通过一个基本示例演示属性的工作原理。

为了这个例子,我简化了您的NotNullAttribute以直接从Attribute-

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

现在考虑使用TestClass这个partial并使用Deactivate方法-

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

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

现在您不直接呼叫Deactivate,而是呼叫'CallDeactivate'-

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

这将起作用并抛出ArgumentNullExceptionCallDeactivate函数的作用是读取Deactivate函数参数的元数据,并执行您希望属性定义的任何功能。 EntityFramework使用类似的方法来执行数据协定属性。

希望这能回答您的问题。