Reputation: 407
I'm starting a new project targeted .net 5
using ASP.NET Core 5
.
Sometimes in some Actions
in some Controllers
I need to check the received model
if it is valid or not, so I created an ActionFilter
class to use with any Action
I want, all these actions will be HttpPost
and will receive a model
.
The problem is I tired from thinking about the best solution to know if the model is an entity or not from OnActionExecuting
method, so I decided to make all my entities inherited from an interface
named IEntity
and in OnActionExecuting
method check if a parameter is inherited from IEntity
and check it's value as shown below.
What I try :
public class ValidationFilterAttribute : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
var param = context.ActionArguments.SingleOrDefault(p => p.Value is IEntity);
if(param.Value == null)
{
context.Result = new BadRequestObjectResult("Object is null");
return;
}
if(!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
Question :
Please is there any good method or technique to know if the model
or one of the context
parameters
is an Entity without using Interface?
Upvotes: 1
Views: 944
Reputation: 63377
Defining a marker interface for your entity types is not a bad idea. But it's not always applicable depending on your design. With the entity type itself, you cannot tell the difference from the normal types. But with the help of the DbContext
containing the entity types, you can check if a type is an entity type by using the method IModel.FindEntityType
public class ValidationFilterAttribute : IActionFilter
{
readonly YourDbContext _dbContext;
public ValidationFilterAttribute(YourDbContext dbContext){
_dbContext = dbContext;
}
public void OnActionExecuting(ActionExecutingContext context)
{
var hasAtLeastOneEntity = context.ActionArguments
.Any(e => e.Value != null &&
_dbContext.Model.FindEntityType(e.Value.GetType()) != null);
if(!hasAtLeastOneEntity)
{
context.Result = new BadRequestObjectResult("Object is null");
return;
}
if(!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
As in the code above, I assume that your DbContext
type is YourDbContext
, you can replace it with your actual DbContext
type.
The performance should be good enough but in case you want it super fast (after performing some benchmarking and find it a bit slow), you can apply some caching strategy on the entity types. Although I'm not so sure if the default implementation of IModel
itself should use some internal cache to manage the entity types.
Upvotes: 1