I'm working on an Asp.net core 5
project targeted .Net 5
, I try to create an Action filter
that will receive a property name, and he will recieve a TEntity
generic type (represent the table to select from) and catch the submitted model
and get the property value from it (model
), this Action Filter
will look in database if a record already has the same value in the past property inside the table passed in TEntity
.
My 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 )
{
}
}
The problem:
When I try to apply the filter on my action I don't know how to pass the PropertyToBeChecked
value.
I paused here :
[TypeFilter(typeof(RecordShouldNotExistFilter<PedagogicalSequence>))]
public async Task<IActionResult> Create( PedagogicalSequenceModel model )
{
}
The question :
How can I pass the PropertyToBeChecked
value ? or how to achieve my object with another way ? except using Action
parameters
You can get the property to be checked in the constructor of your filter, like so:
public RecordShouldNotExistFilter(AppDbContext dbContext, string propertyToBeChecked)
{
_dbContext = dbContext;
PropertyToBeChecked = propertyToBeChecked;
}
And then pass that value into the filter attribute:
[TypeFilter(typeof(RecordShouldNotExistFilter<PedagogicalSequence>), Arguments = new object[] { "PropertyName" })]
public async Task<IActionResult> Create(PedagogicalSequenceModel model)
{
}
Generic attributes aren't supported so your other option is to make a non-generic attribute following this answer and get the entity type through a Type
parameter. You would then use reflection to get the generic implementation:
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;
}
}
This would allow you to do this instead:
[RecordShouldNotExistFilter(typeof(PedagogicalSequenceModel), "PropertyName")]
public async Task<IActionResult> Create(PedagogicalSequenceModel model)