首页 > 解决方案 > 我怎样才能让我的财产验证工作?

问题描述

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

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

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方法的属性?

标签: c#

解决方案


你想要达到的目标是有道理的。但是,您尝试实现的方式将行不通,至少按照您的意图是行不通的。请记住,属性将信息添加到元数据而不是方法本身。我将通过一个基本示例来演示属性如何工作。

为了这个例子,我已经简化了你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);

这将起作用并且会抛出ArgumentNullException. CallDeactivate函数所做的是读取函数参数的元数据并Deactivate执行您希望属性定义的任何功能。EntityFramework 使用类似的方法来执行数据契约属性。

希望这能回答你的问题。


推荐阅读