public void OnActionExecuted(ActionExecutedContext context) { Exception exceptionResult = null; object resultObject = null; Type destinationType = null; var filterDescriptor = context .ActionDescriptor .FilterDescriptors .SingleOrDefault(d => d.Filter.GetType() == typeof(ExpandResultAttribute)); if (!_expandAllEndpoints) { //Cast the filter property to ExpandResultAttribute var attributeInstance = filterDescriptor?.Filter as ExpandResultAttribute; //If the attribute is null, i.e. not present, or false, it shouldn't expand and we return here if (!(attributeInstance?.ShouldExpand ?? false)) { return; } } if (filterDescriptor != null) { destinationType = ((ExpandResultAttribute)filterDescriptor.Filter).DestinationType; } var doNotExpandAttribute = context .ActionDescriptor .FilterDescriptors .SingleOrDefault(d => d.Filter.GetType() == typeof(DoNotExpandResultAttribute)); if (doNotExpandAttribute != null) { return; } // Set the error out of the gate should something have gone wrong coming into Popcorn if (context.Exception != null) { exceptionResult = context.Exception; if (context.HttpContext.Response.StatusCode == 200) { context.HttpContext.Response.StatusCode = 500; } context.ExceptionHandled = true; // Setting this so the inspector is still respected } else if (context.Result is ObjectResult) // Disect the response if there is something to unfold and no exception { resultObject = ((ObjectResult)context.Result).Value; // Wrap the main work here in a try/catch that we can then pass to our inspector try { if (_expander.WillExpand(resultObject)) { // see if we can find some include statements string includes = "[]"; if (context.HttpContext.Request.Query.ContainsKey("include")) { includes = context.HttpContext.Request.Query["include"]; } else if (context.HttpContext.Request.Headers?.ContainsKey("API-INCLUDE") ?? false) { includes = context.HttpContext.Request.Headers["API-INCLUDE"]; } // Use our expander and expand the object resultObject = _expander.Expand(resultObject, _context, PropertyReference.Parse(includes), destinationTypeHint: destinationType); } // Sort should there be anything to sort if (resultObject != null) { // Assign sortDirection where necessary, but default to Ascending if nothing passed in SortDirection sortDirection = SortDirection.Ascending; if (context.HttpContext.Request.Query.ContainsKey("sortDirection")) { // Assign the proper sort direction, but invalidate an invalid value try { sortDirection = (SortDirection)Enum.Parse(typeof(SortDirection), context.HttpContext.Request.Query["sortDirection"]); } catch (ArgumentException) { throw new ArgumentException(context.HttpContext.Request.Query["sortDirection"]); } } // Do any sorting as specified if (context.HttpContext.Request.Query.ContainsKey("sort")) { resultObject = _expander.Sort(resultObject, context.HttpContext.Request.Query["sort"], sortDirection); } } } catch (Exception e) { exceptionResult = e; // Set the response code as appropriate for a caught error context.HttpContext.Response.StatusCode = 500; } } else { return; } // Apply our inspector to the expanded content if (_inspector != null) { resultObject = _inspector(resultObject, _context, exceptionResult); } else if (exceptionResult != null) // Have to rethrow the error if there is no inspector set so as to not return false positives { throw exceptionResult; } context.Result = new JsonResult(resultObject, _jsonOptions); }
public override void OnActionExecuted(ActionExecutedContext context) { Exception exceptionResult = null; object resultObject = null; // Set the error out of the gate should something have gone wrong coming into Popcorn if (context.Exception != null) { exceptionResult = context.Exception; if (context.HttpContext.Response.StatusCode == 200) { context.HttpContext.Response.StatusCode = 500; } context.ExceptionHandled = true; // Setting this so the inspector is still respected } else if (context.Result is ObjectResult) // Disect the response if there is something to unfold and no exception { resultObject = ((ObjectResult)context.Result).Value; // Wrap the main work here in a try/catch that we can then pass to our inspector try { if (_expander.WillExpand(resultObject)) { // see if we can find some include statements string includes = "[]"; if (context.HttpContext.Request.Query.ContainsKey("include")) { includes = context.HttpContext.Request.Query["include"]; } else if (context.HttpContext.Request.Headers?.ContainsKey("API-INCLUDE") ?? false) { includes = context.HttpContext.Request.Headers["API-INCLUDE"]; } // Use our expander and expand the object resultObject = _expander.Expand(resultObject, _context, PropertyReference.Parse(includes)); } // Sort should there be anything to sort if (resultObject != null) { // Assign sortDirection where necessary, but default to Ascending if nothing passed in SortDirection sortDirection = SortDirection.Ascending; if (context.HttpContext.Request.Query.ContainsKey("sortDirection")) { // Assign the proper sort direction, but invalidate an invalid value try { sortDirection = (SortDirection)Enum.Parse(typeof(SortDirection), context.HttpContext.Request.Query["sortDirection"]); } catch (ArgumentException) { throw new ArgumentException(context.HttpContext.Request.Query["sortDirection"]); } } // Do any sorting as specified if (context.HttpContext.Request.Query.ContainsKey("sort")) { resultObject = _expander.Sort(resultObject, context.HttpContext.Request.Query["sort"], sortDirection); } } } catch (Exception e) { exceptionResult = e; // Set the response code as appropriate for a caught error context.HttpContext.Response.StatusCode = 500; } } // Apply our inspector to the expanded content if (_inspector != null) { resultObject = _inspector(resultObject, _context, exceptionResult); } else if (exceptionResult != null) // Have to rethrow the error if there is no inspector set so as to not return false positives { throw exceptionResult; } context.Result = new JsonResult(resultObject, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); base.OnActionExecuted(context); }