/// <summary> /// The token key, which might be a property of the <paramref name="application"/> object or an /// application value in the application data. /// </summary> /// <param name="application">The application to source data from.</param> /// <param name="token">The token key.</param> /// <param name="path">Specifies the path to the token. Defaults to <see langword="null"/>.</param> /// <returns>The value of the token.</returns> /// <remarks>Order of precedence: (1) <paramref name="application"/> object; (2) application data.</remarks> public static object GetTokenValue(this Application application, string token, ApplicationDataPath path = null) { object tokenValue; if (application.TryGetPropertyValue(token, '.', out tokenValue)) { return tokenValue; } // We are going to be be popping items so we should create our own copy of the path. ApplicationDataPath pathIterator = new ApplicationDataPath(path ?? new ApplicationDataPath()); string tokenPath = pathIterator.ToString(token); tokenValue = application.ApplicationData.GetValue<object>(tokenPath, null); while (tokenValue == null && pathIterator.Count != 0) { pathIterator.TraverseUp(); tokenPath = pathIterator.ToString(token); tokenValue = application.ApplicationData.GetValue<object>(tokenPath, null); } return tokenValue; }
/// <summary> /// Implements the validation logic for the receiver. /// </summary> /// <param name="objectToValidate">The object to validate.</param> /// <param name="currentTarget">The object on the behalf of which the validation is performed.</param> /// <param name="key">The key that identifies the source of objectToValidate.</param> /// <param name="validationResults">The validation results to which the outcome of the validation should be stored.</param> public override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults) { if (objectToValidate == null) { return; } object[] arr = (object[])objectToValidate; Dictionary<string, object>[] items = arr.Length > 0 ? objectToValidate as Dictionary<string, object>[] : new Dictionary<string, object>[0]; for (int i = 0; i < items.Length; i++) { Dictionary<string, object> item = items[i]; ApplicationDataPath path = new ApplicationDataPath(key); path.Last().Index = i; this.WrappedValidator.DoValidate(item, currentTarget, path.ToString(), validationResults); } }
/// <summary> /// Implements the validation logic for the receiver. /// </summary> /// <param name="objectToValidate">The object to validate.</param> /// <param name="currentTarget">The object on the behalf of which the validation is performed.</param> /// <param name="key">The key that identifies the source of objectToValidate.</param> /// <param name="validationResults">The validation results to which the outcome of the validation should be stored.</param> public override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults validationResults) { if (objectToValidate == null) { return; } ControlValueValidator controlValueValidator = this.WrappedValidator as ControlValueValidator; LikertControl likert = this.AllControls.FindRecursive<LikertControl>(key); Dictionary<string, object> items = objectToValidate as Dictionary<string, object>; ApplicationDataPath path = new ApplicationDataPath(key); foreach (KeyValuePair<string, object> item in items) { string tag = likert.Questions.First(q => q.Name == item.Key).Label; controlValueValidator.SetTag(tag); this.WrappedValidator.DoValidate(item.Value, currentTarget, path.ToString(item.Key), validationResults); } }
public void TokenAtRoot() { ApplicationDataPath path = new ApplicationDataPath(); Assert.AreEqual("token", path.ToString("token")); }
public void TokenAtLevelTwo() { ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("Inner", 3); path.Prepend("Outer", 2); Assert.AreEqual("Outer[2].Inner[3].token", path.ToString("token")); }
public void TokenAtLevelOne() { ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("Repeater1", 2); Assert.AreEqual("Repeater1[2].token", path.ToString("token")); }
public void HasEmptyIndex() { ApplicationDataPath path = new ApplicationDataPath(); path.Prepend("Inner", null); Assert.AreEqual("Inner.token", path.ToString("token")); }
/// <summary> /// Runs a calculation for all instances of a repeater and adds the result to <paramref name="resultsContainer"/>. /// </summary> /// <param name="control">The calculation to run.</param> /// <param name="relativePath">The relative path to <paramref name="control"/> within <paramref name="resultsContainer"/> and <paramref name="applicationContainer"/>.</param> /// <param name="absolutePath">The absolute path to <paramref name="control"/> from the root of the application data.</param> /// <param name="resultsContainer">A dictionary of results.</param> /// <param name="applicationContainer">The application data container.</param> /// <param name="exceptionList">A list that <see cref="ExpressionEvaluatorException"/>s will be added to before returning to the client.</param> private void CalculateRepeater(CalculationControl control, ApplicationDataPath relativePath, ApplicationDataPath absolutePath, Dictionary<string, object> resultsContainer, Dictionary<string, object> applicationContainer, List<ExpressionEvaluatorException> exceptionList) { if (relativePath.Count == 0) { try { var result = this.Evaluate(control.CalculationExpression, absolutePath); resultsContainer[control.Name] = result; applicationContainer[control.Name] = result; } catch (ExpressionEvaluatorException e) { e.Tag = absolutePath.ToString(control.Name); exceptionList.Add(e); } return; } ApplicationDataPathSegment segment = relativePath.TraverseDown(); Dictionary<string, object>[] repeaterCalculationResults = (Dictionary<string, object>[])resultsContainer[segment.Name]; Dictionary<string, object>[] repeaterApplicationData = applicationContainer.GetRepeaterItemsOrDefault(segment.Name); for (var i = 0; i < repeaterCalculationResults.Length; i++) { segment.Index = i; absolutePath.FirstOrDefault(s => s.Name == segment.Name).Index = segment.Index; this.CalculateRepeater(control, new ApplicationDataPath(relativePath), absolutePath, repeaterCalculationResults[i], repeaterApplicationData[i], exceptionList); } }
/// <summary> /// Converts a string in format <code>RepeaterName-Index-FieldName</code> to a string based /// repeater path in the format <code>RepeaterName[Index].FieldName</code> which is used to /// pre-populate application data. /// </summary> /// <param name="paramKey">The parameter key.</param> /// <param name="repeaterRegex">The repeater regex.</param> /// <returns>A string based repeater path in the format <code>RepeaterName[Index].FieldName</code></returns> private string DetermineRepeaterPath(string paramKey, Regex repeaterRegex) { Match match = repeaterRegex.Match(paramKey); ApplicationDataPath path = new ApplicationDataPath(); path.Append(match.Groups["RepeaterName"].Value, int.Parse(match.Groups["Index"].Value)); return path.ToString(match.Groups["FieldName"].Value); }