ASP.NET MVC 通过ActionFilter 实现AOP设计 示例

在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.");
            }
        }
    }

你可能感兴趣的:(C#/DNX,Net-MVC)