asp.net-web-api
Création d'un ActionFilterAttribute personnalisé
Recherche…
Introduction
Filtres d'action Les attributs font partie du framework ASP .NET que je trouve utile pour suivre le principe DRY. Vous pouvez remplacer plusieurs lignes de logique commune par une simple balise déclarative. Le framework fournit par défaut plusieurs attributs de filtre d'action, tels que les attributs d'erreur Authorize et Handle. Ce guide est destiné à vous montrer comment créer votre propre attribut personnalisé.
EnsurePresenseOfAttribute
Voici un exemple d'attribut que j'ai créé pour valider que les paramètres requis ont été attribués dans l'objet de requête reçu dans un itinéraire POST. J'ai choisi cette approche car l'approche standard ModelState.IsValid n'était pas valide. En effet, les attributs requis varient en fonction de l'action appelée.
// ATTRIBUT UNIQUEMENT VALABLE POUR METHODS [AttributeUsage (AttributeTargets.Method)] // INHERIT ActionFilterAttribute classe publique EnsurePresencesOfAttribute: ActionFilterAttribute {// ReSharper disable une fois InconsistentNaming public string required {get; ensemble; }
// VALIDATE REQUIRED ATTRIBUTES
// FOR NON-ASYNC REQUESTS
public override void OnActionExecuting(HttpActionContext context)
{
Dictionary<string, object> model = context.ActionArguments;
var serialstring = JsonConvert.SerializeObject(model);
foreach (var requirement in required.Split(','))
{
if (serialstring.Contains($"{requirement}\":null"))
{
ValueError(context, requirement);
return;
}
}
base.OnActionExecuting(context);
}
// VALIDATE THE REQUIRED ATTRIBUTES ARE PRESENT
// FOR ASYNC REQUESTS
public override Task OnActionExecutingAsync(HttpActionContext context, CancellationToken token)
{
Dictionary<string, object> model = context.ActionArguments;
var serialstring = JsonConvert.SerializeObject(model);
foreach (var requirement in required.Split(','))
{
if (serialstring.Contains($"{requirement}\":null"))
{
ValueError(context, requirement);
return Task.FromResult(0);
}
}
return base.OnActionExecutingAsync(context, token);
}
// LOG ERROR AND RETURN AND SET ERROR RESPONSE
private static void ValueError(HttpActionContext context, string requirement)
{
var action = context.ActionDescriptor.ActionName;
AppUtils.LogError($"{action} Failed : Missing Required Attribute {requirement}. ");
using (var controller = new BaseApiController { Request = new HttpRequestMessage() })
{
controller.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
context.Response = controller.InvalidInputResponse();
}
}
Contrôleur avant l'attribut EnsuresPresenseOf
[HttpPost]
[Route("api/Fitbit/Activity/Stats")]
public async Task<HttpResponseMessage> ActivityStats(FitbitRequestDTO request)
{
if (string.IsNullOrEmpty(request.PatientId) || string.IsNullOrEmpty(request.DeviceId))
return InvalidInputResponse();
try
{
var tokenErrorResponse = await EnsureToken(request);
if (tokenErrorResponse != null)
return tokenErrorResponse;
var client = GetFitbitClient();
var stats = await client.GetActivitiesStatsAsync();
return OkResponse(stats);
}
catch (Exception e)
{
const string function = " ActivityStats ";
AppUtils.LogException(function, e);
return SystemErrorResponse(function, e);
}
}
Mettre à jour le contrôleur
public async Task<HttpResponseMessage> ActivityStats(FitbitRequestDTO request)
{
try
{
var tokenErrorResponse = await EnsureToken(request);
if (tokenErrorResponse != null)
return tokenErrorResponse;
var client = GetFitbitClient();
var stats = await client.GetActivitiesStatsAsync();
return OkResponse(stats);
}
catch (Exception e)
{
const string function = " ActivityStats ";
AppUtils.LogException(function, e);
return SystemErrorResponse(function, e);
}
}