サーチ…


前書き

アクションフィルタ属性は、ASP .NET Frameworkの一部であり、DRYの原則に従うのに役立ちます。いくつかの共通ロジックを1つの単純な宣言タグで置き換えることができます。このフレームワークは、デフォルトでは、「エラーの認可」および「エラー処理」属性など、いくつかの有用なアクション・フィルタ属性を提供します。このガイドでは、独自のカスタム属性を作成する方法を説明します。

EnsurePresenseOfAttribute

これは、POSTルートで要求オブジェクトを受信する際に必要なパラメータが割り当てられていることを検証するために作成した属性の例です。標準的なModelState.IsValidアプローチが有効でないため、このアプローチを決めました。これは、どのアクションが呼び出されているかによって必要な属性が異なるためです。

//メソッドの唯一の有効な属性[AttributeUsage(AttributeTargets.Method)] // INHERIT ActionFilterAttribute publicクラスEnsurePresencesOfAttribute:ActionFilterAttribute {// ReSharperは一度無効にするInconsistentNaming public string required {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();
    }
}

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);
            }
        }

コントローラの更新

        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);
            }
        }


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow