ASP.NET MVCによるActionFilterによるAOP設計例

5187 ワード

Asp.Net MVCフレームワークでは、ActionFilterでリクエストをブロックし、リクエストを一定の処理をしてからActionにデータ処理を渡すことができます.また,ActionFilterを用いてActionの戻り値を統一処理し,クライアント呼び出しに返すことも可能である.ActionFilterとの合理的な利用により,AOP設計を容易に実現でき,コード分離の効果が得られる.ここでは、コミュニケーション学習のための例を共有します.
この例では、データストリームのブロックとパラメータの注入が実現される.
   public class MyIntercepterAttribute : FilterAttribute, IActionFilter
    {
        private const string nodeName = "someNode";
        public void OnActionExecuting(ActionExecutingContext actionContext)
        {
            var inputStream = actionContext.HttpContext.Request.InputStream;
            inputStream.Position = 0;
            string payloadStr;
            using (var streamReader = new StreamReader(inputStream))
            {//      
                payloadStr = streamReader.ReadToEnd();
            }

            if (string.IsNullOrWhiteSpace(payloadStr))
            {
                throw new HttpException(400, "Invalid payload");
            }

            var wrapper = (JObject)JsonConvert.DeserializeObject(payloadStr);
            var originalDataNode = wrapper[nodeName];

            if (originalDataNode == null)
            {
                throw new HttpException(400, "Invalid schema.");
            }

            //         Json           。
            var plainRequest = originalDataNode.ToObject<string>();
            var requestRootNode = (JObject)JsonConvert.DeserializeObject(plainRequest);

            var parameters = actionContext.ActionDescriptor.GetParameters();
            var jsonSerializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver() };
            foreach (var param in parameters)
            {//       /   Action    
                JToken matchedParamNode;
                requestRootNode.TryGetValue(param.ParameterName, StringComparison.CurrentCultureIgnoreCase, out matchedParamNode) ;
                if (matchedParamNode != null)
                {
                    actionContext.ActionParameters[param.ParameterName] = matchedParamNode.ToObject(param.ParameterType, jsonSerializer);
                }
                else if (param.ParameterType.IsClass && param.ParameterType != typeof(string))
                {
                    actionContext.ActionParameters[param.ParameterName] = requestRootNode.ToObject(param.ParameterType, jsonSerializer);
                }
            }
        }

        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            var result = filterContext.Result;
            if (result is JsonResult)
            {//   Action    
                var jsonResult = result as JsonResult;
                var handledResponse = JsonConvert.SerializeObject(jsonResult.Data);

                jsonResult.Data = new { Result = handledResponse };
            }
            else
            {
                throw new  NotImplementedException("Currently, this sample only support json result.");
            }
        }
    }