asp.net-web-api
Tworzenie niestandardowego atrybutu ActionFilterAttribute
Szukaj…
Wprowadzenie
Filtry akcji Atrybuty są częścią środowiska ASP .NET Framework, które uważam za przydatne, aby pomóc w przestrzeganiu zasady DRY. Możesz zastąpić kilka wierszy wspólnej logiki jednym prostym znacznikiem deklaratywnym. Struktura domyślnie udostępnia kilka przydatnych atrybutów filtru akcji, takich jak autoryzacja i obsługa atrybutów błędów. Ten przewodnik ma na celu pokazać, jak utworzyć własny atrybut niestandardowy.
ZapewnijPresenseOfAttribute
To jest przykład atrybutu, który utworzyłem w celu sprawdzenia, czy wymagane parametry zostały przypisane w obiekcie żądania odbierania na trasie POST. Zdecydowałem się na to podejście, ponieważ standardowe podejście ModelState.IsValid było nieprawidłowe. Jest tak, ponieważ wymagane atrybuty różnią się w zależności od wywoływanej akcji.
// AKTYWNY TYLKO DLA METOD [AttributeUsage (AttributeTargets.Method)] // INHERIT ActionFilterAttribute klasa publiczna ZapewnijPresencesOfAttribute: ActionFilterAttribute {// ReSharper wyłącz, gdy wymagany jest ciąg publiczny InconsistentNaming {get; zestaw; }
// 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();
}
}
Kontroler przed zapewnieniem atrybutu PresenseOf
[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);
}
}
Zaktualizuj kontroler
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);
}
}