首页 > 解决方案 > 如何将参数传递给通用动作过滤器

问题描述

我正在开发一个Asp.net core 5目标项目.Net 5,我尝试创建一个Action filter将接收属性名称的项目,他将收到一个TEntity通用类型(表示要从中选择的表)并捕获提交model并从中获取属性值(model),如果一条记录在传入的表中的过去属性中已经具有相同的值,这Action Filter将在数据库中查找TEntity

我的操作过滤器:

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参数

标签: c#asp.net-core.net-5action-filter

解决方案


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

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)

推荐阅读