如何将参数传递给通用 Action 过滤器

How to pass parameters to a generic Action filter

我正在开发一个针对 .Net 5Asp.net core 5 项目,我尝试创建一个 Action filter,它将获得一个 属性 名称,他将获得一个TEntity 泛型(表示从 table 到 select )并捕获提交的 model 并从中获取 属性 值 (model) , 如果在 TEntity.

中传递的 table 中的记录在过去 属性 中已经具有相同的值,则此 Action Filter 将在数据库中查找

我的操作过滤器:

public class RecordShouldNotExistFilter<TEntity>:IActionFilter where  TEntity : class
{

    private readonly AppDbContext _dbContext;
    public           string     PropertyToBeChecked { get; set; }

    public RecordShouldNotExistFilter( AppDbContext dbContext )
    {
        _dbContext = dbContext;
    }

    public void OnActionExecuting( ActionExecutingContext context )
    {
      // Some logic here that uses the PropertyToBeChecked's value
    }


    }

    public void OnActionExecuted( ActionExecutedContext   context )
    {
        
    }

}

问题: 当我尝试对我的操作应用过滤器时,我不知道如何传递 PropertyToBeChecked 值。

我在这里暂停了:

[TypeFilter(typeof(RecordShouldNotExistFilter<PedagogicalSequence>))]
public async Task<IActionResult> Create( PedagogicalSequenceModel model )
{
}

问题: 如何传递 PropertyToBeChecked 值?或者如何用另一种方式实现我的目标?除了使用 Action 参数

您可以在过滤器的构造函数中检查 属性,如下所示:

public RecordShouldNotExistFilter(AppDbContext dbContext, string propertyToBeChecked)
{
    _dbContext = dbContext;
    PropertyToBeChecked = propertyToBeChecked;
}

然后将该值传递给过滤器属性:

[TypeFilter(typeof(RecordShouldNotExistFilter<PedagogicalSequence>), Arguments = new object[] { "PropertyName" })]
public async Task<IActionResult> Create(PedagogicalSequenceModel model)
{
}

不支持通用属性,因此您的另一个选择是在 之后创建一个非通用属性,并通过 Type 参数获取实体类型。然后您将使用反射来获取通用实现:

public class RecordShouldNotExistFilterAttribute : TypeFilterAttribute
{
    public RecordShouldNotExistFilterAttribute(Type entityType, string propertyToBeChecked) 
        : base(typeof(RecordShouldNotExistFilter<>).MakeGenericType(entityType))
    {
        Arguments = new object[] { propertyToBeChecked };
    }
}

public class RecordShouldNotExistFilter<TEntity> : IActionFilter where TEntity : class
{
    readonly AppDbContext _dbContext;
    public string PropertyToBeChecked { get; set; }

    public RecordShouldNotExistFilter(AppDbContext dbContext, string propertyToBeChecked)
    {
        _dbContext = dbContext;
        PropertyToBeChecked = propertyToBeChecked;
    }
}

这将允许您改为这样做:

[RecordShouldNotExistFilter(typeof(PedagogicalSequenceModel), "PropertyName")]
public async Task<IActionResult> Create(PedagogicalSequenceModel model)