asp.net-web-api
Creando un ActionFilterAttribute personalizado
Buscar..
Introducción
Los atributos de los filtros de acción son parte de ASP .NET Framework que me parece útil para ayudar a seguir el principio DRY. Puede reemplazar varias líneas de lógica común con una etiqueta declarativa simple. El marco proporciona varios atributos de filtro de acción útiles de forma predeterminada, como los atributos de error de autorización y manejo. Esta guía está diseñada para mostrarle cómo crear su propio atributo personalizado.
AsegurarPensenseOfAtributo
Este es un ejemplo de un atributo que creé para validar que los parámetros requeridos han sido asignados en el objeto de solicitud recibido en una ruta POST. Me decidí por este enfoque porque el enfoque estándar de ModelState.IsValid no era válido. Esto se debe a que los atributos requeridos varían según la acción que se está llamando.
// ATTRIBUTE ONLY VALID FOR METHODS [AttributeUsage (AttributeTargets.Method)] // INHERIT ActionFilterAttribute public class VerifyPresencesOfAttribute: ActionFilterAttribute {// ReSharper disable once InconsistentNaming public string required {get; conjunto; }
// 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();
}
}
Controlador antes del atributo 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);
}
}
Actualizar controlador
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);
}
}