private static void RewriteAllLinks(object model, LinkRewriter rewriter) { if (model == null) { return; } var allProperties = model .GetType().GetTypeInfo() .GetAllProperties() .Where(p => p.CanRead) .ToArray(); var linkProperties = allProperties .Where(p => p.CanWrite && p.PropertyType == typeof(Link)); foreach (var linkProperty in linkProperties) { var rewritten = rewriter.Rewrite(linkProperty.GetValue(model) as Link); if (rewritten == null) { continue; } linkProperty.SetValue(model, rewritten); // Special handling of the hidden Self property: // unwrap into the root object if (linkProperty.Name == nameof(Resource.Self)) { allProperties .SingleOrDefault(p => p.Name == nameof(Resource.Href)) ?.SetValue(model, rewritten.Href); allProperties .SingleOrDefault(p => p.Name == nameof(Resource.Method)) ?.SetValue(model, rewritten.Method); allProperties .SingleOrDefault(p => p.Name == nameof(Resource.Relations)) ?.SetValue(model, rewritten.Relations); } } var arrayProperties = allProperties.Where(p => p.PropertyType.IsArray); RewriteLinksInArrays(arrayProperties, model, rewriter); var objectProperties = allProperties .Except(linkProperties) .Except(arrayProperties); RewriteLinksInNestedObjects(objectProperties, model, rewriter); }
private static void RewriteLinksInArrays( IEnumerable <PropertyInfo> arrayProperties, object model, LinkRewriter rewriter) { foreach (var arrayProperty in arrayProperties) { var array = arrayProperty.GetValue(model) as Array ?? new Array[0]; foreach (var element in array) { RewriteAllLinks(element, rewriter); } } }
private static void RewriteLinksInNestedObjects( IEnumerable <PropertyInfo> objectProperties, object model, LinkRewriter rewriter) { foreach (var objectProperty in objectProperties) { if (objectProperty.PropertyType == typeof(string)) { continue; } var typeInfo = objectProperty.PropertyType.GetTypeInfo(); if (typeInfo.IsClass) { RewriteAllLinks(objectProperty.GetValue(model), rewriter); } } }
public Task OnResultExecutionAsync( ResultExecutingContext context, ResultExecutionDelegate next) { var asObjectResult = context.Result as ObjectResult; bool shouldSkip = asObjectResult?.StatusCode >= 400 || asObjectResult?.Value == null || asObjectResult?.Value as Resource == null; if (shouldSkip) { return(next()); } var rewriter = new LinkRewriter(_urlHelperFactory.GetUrlHelper(context)); RewriteAllLinks(asObjectResult.Value, rewriter); return(next()); }