public async Task <ActionResult> GetAsync([FromRoute] string path) { var allParams = PartitionByKey(HttpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value), x => x.StartsWith("$")); var modifiers = allParams.Item1; var isFlatten = modifiers.TryGetValue("$flatten").Select(x => bool.Parse(x.First())).IfNone(false); var includeErrors = modifiers.TryGetValue("$includeErrors").Select(x => bool.Parse(x.First())).IfNone(false); var ignoreKeyTypes = modifiers.TryGetValue("$ignoreKeyTypes").Select(x => bool.Parse(x.First())).IfNone(false); var includePaths = modifiers.TryGetValue("$include").Select(x => x.ToArray()).IfNone(new string[] {}); var translateValue = ignoreKeyTypes ? (TranslateValue)TranslateValueToString : (x => x.Value); IReadOnlyDictionary <string, JsonValue> contextParams = allParams.Item2.ToDictionary(x => x.Key, x => x.Value.Count == 1 ? JsonValue.NewString(x.Value.ToString()) : JsonValue.NewArray(x.Value.Map(t => JsonValue.NewString(t)).ToArray()), StringComparer.OrdinalIgnoreCase); var identities = new IdentityHashSet(contextParams.Where(x => !x.Key.Contains(".")).Select(x => new Identity(x.Key, x.Value.AsString()))); if (!_checkAccess(User, path, identities)) { return(Forbid()); } GetLoadedContextByIdentityType contextProps = identityType => key => contextParams.TryGetValue($"{identityType}.{key}"); var root = ConfigurationPath.New(path); var query = GetQuery(root, includePaths); var values = await _tweek.GetContextAndCalculate(query, identities, _contextDriver, contextProps); var errors = values.Where(x => x.Value.Exception != null).ToDictionary(x => x.Key, x => x.Value.Exception.Message); Response.Headers.Add("X-Error-Count", errors.Count.ToString()); object result = null; if (root.IsScan) { var relativeData = values.Where(x => x.Value.Exception == null).ToDictionary(x => x.Key.ToRelative(root), x => x.Value); result = !isFlatten ? TreeResult.From(relativeData, translateValue) : relativeData.ToDictionary(x => x.Key.ToString(), x => translateValue(x.Value)); } else if (values.TryGetValue(root, out var value) && value.Exception == null) { result = ignoreKeyTypes ? TranslateValueToString(value) : value.Value; } if (!includeErrors) { return(Json(result)); } return(Json(new Dictionary <string, object> { { "data", result }, { "errors", errors } })); }
public async Task <ActionResult> GetAsync([FromRoute] string path) { var allParams = PartitionByKey(HttpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value), x => x.StartsWith("$")); var modifiers = allParams.Item1; var isFlatten = modifiers.TryGetValue("$flatten").Select(x => bool.Parse(x.First())).IfNone(false); var ignoreKeyTypes = modifiers.TryGetValue("$ignoreKeyTypes").Select(x => bool.Parse(x.First())).IfNone(false); var includePaths = modifiers.TryGetValue("$include").Select(x => x.ToArray()).IfNone(new string[] {}); var translateValue = ignoreKeyTypes ? (TranslateValue)TranslateValueToString : (x => x.Value); IReadOnlyDictionary <string, JsonValue> contextParams = allParams.Item2.ToDictionary(x => x.Key, x => JsonValue.NewString(x.Value.ToString()), StringComparer.OrdinalIgnoreCase); var identities = new IdentityHashSet(contextParams.Where(x => !x.Key.Contains(".")).Select(x => new Identity(x.Key, x.Value.AsString()))); if (!_checkAccess(User, path, identities)) { return(Forbid()); } GetLoadedContextByIdentityType contextProps = identityType => key => contextParams.TryGetValue($"{identityType}.{key}"); var root = ConfigurationPath.New(path); var query = GetQuery(root, includePaths); var data = await _tweek.GetContextAndCalculate(query, identities, _contextDriver, contextProps); if (root.IsScan) { var relativeData = data.ToDictionary(x => x.Key.ToRelative(root), x => x.Value); return(Json(!isFlatten ? (TreeResult.From(relativeData, translateValue)) : relativeData.ToDictionary(x => x.Key.ToString(), x => translateValue(x.Value)))); } return(data.Select(x => ignoreKeyTypes ? (object)x.Value.Value.AsString() : x.Value.Value) .FirstOrNone() .Match(x => Json(x), () => Json(null))); }