asp.net-web-api
Создание пользовательского ActionFilterAttribute
Поиск…
Вступление
Action Filters Атрибуты являются частью ASP.NET Framework, которые я считаю полезными, чтобы помочь следовать принципу DRY. Вы можете заменить несколько строк общей логики одним простым декларативным тегом. По умолчанию Framework предоставляет несколько полезных атрибутов Action Filter, таких как атрибуты Authorize и Handle Error. Это руководство предназначено, чтобы показать вам, как создать свой собственный пользовательский атрибут.
EnsurePresenseOfAttribute
Это пример атрибута, который я создал для проверки того, что требуемые параметры были назначены при получении запроса на маршруте POST. Я решил использовать этот подход, потому что стандартный подход ModelState.IsValid недействителен. Это связано с тем, что требуемые атрибуты изменяются в зависимости от того, какое действие вызывается.
// ATTRIBUTE ТОЛЬКО ДЕЙСТВИТЕЛЬНО ДЛЯ МЕТОДОВ [AttributeUsage (AttributeTargets.Method)] // INHERIT Открытый класс ActionFilterAttribute EnsurePresencesOfAttribute: ActionFilterAttribute {// ReSharper отключается после того, как была создана общедоступная строка InconsistentNaming {get; задавать; }
// 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();
}
}
Контроллер перед активацией атрибута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);
}
}
Контроллер обновления
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);
}
}