At my workplace, I’ve been tasked with refactoring some code in an ASP.NET Core Web API application. In the application, I have multiple request models where some models include properties like UserId, ChartId, or both. For instance, the AcceptEvent model includes all these properties, while other models might only include ChartId.
I have created a service class to retrieve user claims:
public class UserClaimsService : IUserClaimsService
{
public long ProvinceId { get; }
public long UserId { get; }
public long LoginChart { get; }
public UserClaimsService(IHttpContextAccessor httpContextAccessor)
{
ClaimsPrincipal? user = httpContextAccessor.HttpContext.User;
if (user.Identity.IsAuthenticated && user != null)
{
UserId = long.Parse(user.Claims.First(a => a.Type == ClaimTypes.NameIdentifier).Value);
ProvinceId = long.Parse(user.Claims.First(a => a.Type == "ProvinceId").Value);
LoginChart = long.Parse(user.Claims.First(a => a.Type == "ChartId").Value);
}
}
}
public interface IUserClaimsService
{
public long ProvinceId { get; }
public long UserId { get; }
public long LoginChart { get; }
}
This service is registered with AddScoped. However, I am unsure how to dynamically set these optional properties (e.g., ProvinceId, LoginChart) in the request models consistently.
Is using a global filter a good approach for dynamically setting these properties in request models? How can I achieve this, and are there any performance considerations or best practices I should be aware of?
2
Answers
It should be possible to write a custom binder for request model.
You probably use some of built-in binders, for example [FromQuery] or [FromHeader] attributes. Your custom binder could read claims from current Identity and bind a value based on claim name. More on this in article.
You could use global filters to dynamically set properties in request models. to do that you can follow these below steps:
1)Create a custom action filter that injects the
IUserClaimsService
and sets the relevant properties in the request models.Filters/SetClaimsPropertiesFilter.cs:
2)Create interfaces that your request models can implement to indicate which properties should be set.
Models/IClaimUserId.cs:
Models/IClaimChartId.cs:
3)Implement Interfaces in Request Models:
Models/AcceptEventModel.cs:
Models/AnotherRequestModel.cs:
4)Program.cs: