public IEnumerable<ValidationResult> Validate(object value, PreValueCollection preValues, PropertyEditor editor) { var json = value as JArray; if (json == null) yield break; //validate each item which is a json object for (var index = 0; index < json.Count; index++) { var i = json[index]; var jItem = i as JObject; if (jItem == null || jItem["value"] == null) continue; //NOTE: we will be removing empty values when persisting so no need to validate var asString = jItem["value"].ToString(); if (asString.IsNullOrWhiteSpace()) continue; if (Regex.IsMatch(asString, "^([0-9a-f]{3}|[0-9a-f]{6})$", RegexOptions.IgnoreCase) == false) { yield return new ValidationResult("The value " + asString + " is not a valid hex color", new[] { //we'll make the server field the index number of the value so it can be wired up to the view "item_" + index.ToInvariantString() }); } } }
/// <summary> /// Always /// </summary> /// <param name="defaultPreVals"></param> /// <param name="persistedPreVals"></param> /// <returns></returns> public override IDictionary<string, object> ConvertDbToEditor(IDictionary<string, object> defaultPreVals, PreValueCollection persistedPreVals) { var returnVal = base.ConvertDbToEditor(defaultPreVals, persistedPreVals); //always add the multiple param to true returnVal["multiple"] = "1"; return returnVal; }
public static void ConvertItemValueFromV011(JObject item, int dtdId, ref PreValueCollection preValues) { var contentTypeAlias = GetContentTypeAliasFromItem(item); if (contentTypeAlias != null) { // the item is already in >v0.1.1 format return; } // old style (v0.1.1) data, let's attempt a conversion // - get the prevalues (if they're not loaded already) preValues = preValues ?? GetPreValuesCollectionByDataTypeId(dtdId); // - convert the prevalues (if necessary) ConvertPreValueCollectionFromV011(preValues); // - get the content types prevalue as JArray var preValuesAsDictionary = preValues.AsPreValueDictionary(); if (!preValuesAsDictionary.ContainsKey(ContentTypesPreValueKey) || string.IsNullOrEmpty(preValuesAsDictionary[ContentTypesPreValueKey]) != false) { return; } var preValueContentTypes = JArray.Parse(preValuesAsDictionary[ContentTypesPreValueKey]); if (preValueContentTypes.Any()) { // the only thing we can really do is assume that the item is the first available content type item[NestedContentPropertyEditor.ContentTypeAliasPropertyKey] = preValueContentTypes.First().Value<string>("ncAlias"); } }
public static string GetRowOptionsDocType(PreValueCollection preValueCollection, string cellId) { var preValueDict = preValueCollection.PreValuesAsDictionary.ToDictionary(x => x.Key, x => x.Value.Value); // Check the grid config if (preValueDict.ContainsKey("gridConfig")) { var gridConfig = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, object>>>( preValueDict["gridConfig"].ToString(CultureInfo.InvariantCulture)); if (gridConfig != null && gridConfig.ContainsKey(cellId) && gridConfig[cellId].ContainsKey("rowOptionsDocType")) { return gridConfig[cellId]["rowOptionsDocType"].ToString(); } } // Check the default config if (preValueDict.ContainsKey("defaultConfig")) { var defaultConfig = JsonConvert.DeserializeObject<Dictionary<string, object>>( preValueDict["defaultConfig"].ToString(CultureInfo.InvariantCulture)); if (defaultConfig != null && defaultConfig.ContainsKey("rowOptionsDocType")) { return defaultConfig["rowOptionsDocType"].ToString(); } } return null; }
/// <summary> /// Need to deal with the legacy way of storing pre-values and turn them into nice values for the editor /// </summary> /// <param name="defaultPreVals"></param> /// <param name="persistedPreVals"></param> /// <returns></returns> public override IDictionary<string, object> ConvertDbToEditor(IDictionary<string, object> defaultPreVals, PreValueCollection persistedPreVals) { var preVals = persistedPreVals.FormatAsDictionary(); var stringVal = preVals.Any() ? preVals.First().Value.Value : ""; var returnVal = new Dictionary<string, object> { { "min", 0 }, { "max", 0 } }; if (stringVal.IsNullOrWhiteSpace() == false) { try { var json = JsonConvert.DeserializeObject<JObject>(stringVal); if (json["Minimum"] != null) { //by default pre-values are sent out with an id/value pair returnVal["min"] = json["Minimum"].Value<int>(); } if (json["Maximum"] != null) { returnVal["max"] = json["Maximum"].Value<int>(); } } catch (Exception e) { //this shouldn't happen unless there's already a bad formatted pre-value LogHelper.WarnWithException<MultipleTextStringPreValueEditor>("Could not deserialize value to json " + stringVal, e); return returnVal; } } return returnVal; }
/// <summary> /// This ensures the multiPicker pre-val is set based on the maxNumber of nodes set /// </summary> /// <param name="defaultPreVals"></param> /// <param name="persistedPreVals"></param> /// <returns></returns> /// <remarks> /// Due to compatibility with 7.0.0 the multiPicker pre-val might already exist in the db, but we've removed that setting in 7.0.1 so we need to detect it and if it is /// there, then we'll set the maxNumber to '1' /// </remarks> public override IDictionary<string, object> ConvertDbToEditor(IDictionary<string, object> defaultPreVals, PreValueCollection persistedPreVals) { var result = base.ConvertDbToEditor(defaultPreVals, persistedPreVals); //backwards compatibility check if (result.ContainsKey("multiPicker") && result["multiPicker"].ToString() == "0") { result["maxNumber"] = "1"; } //set the multiPicker val correctly depending on the maxNumber var asNumber = result["maxNumber"].TryConvertTo<int>(); if (asNumber.Success) { if (asNumber.Result <= 1) { result["multiPicker"] = "0"; } else { result["multiPicker"] = "1"; } } return result; }
/// <summary> /// Used when configured as an IPropertyValidator /// </summary> /// <param name="value"></param> /// <param name="preValues"></param> /// <param name="editor"></param> /// <returns></returns> public IEnumerable<ValidationResult> Validate(object value, PreValueCollection preValues, PropertyEditor editor) { if (_regex == null) { throw new InvalidOperationException("This validator is not configured as a " + typeof(IPropertyValidator)); } return Validate(value, _regex, preValues, editor); }
/// <summary> /// The editor is expecting a json array for a field with a key named "items" so we need to format the persisted values /// to this format to be used in the editor. /// </summary> /// <param name="defaultPreVals"></param> /// <param name="persistedPreVals"></param> /// <returns></returns> public override IDictionary<string, object> ConvertDbToEditor(IDictionary<string, object> defaultPreVals, PreValueCollection persistedPreVals) { var dictionary = persistedPreVals.FormatAsDictionary(); var arrayOfVals = dictionary.Select(item => item.Value).ToList(); //the items list will be a dictionary of it's id -> value we need to use the id for persistence for backwards compatibility return new Dictionary<string, object> { { "items", arrayOfVals.ToDictionary(x => x.Id, x => x.Value) } }; }
/// <summary> /// Chuck all the values into one field so devs can see what is stored there - we want this in case we've converted a legacy proeprty editor over to a label /// we should still show the pre-values stored for the data type. /// </summary> /// <param name="defaultPreVals"></param> /// <param name="persistedPreVals"></param> /// <returns></returns> public override IDictionary<string, object> ConvertDbToEditor(IDictionary<string, object> defaultPreVals, PreValueCollection persistedPreVals) { var existing = base.ConvertDbToEditor(defaultPreVals, persistedPreVals); //convert to a list, easier to enumerate on the editor var asList = existing.Select(e => new KeyValuePair<string, object>(e.Key, e.Value)).ToList(); var result = new Dictionary<string, object> { { "values", asList } }; return result; }
/// <summary> /// Need to change how we persist the values so they are compatible with the legacy way we store values /// </summary> /// <param name="editorValue"></param> /// <param name="currentValue"></param> /// <returns></returns> public override IDictionary<string, PreValue> ConvertEditorToDb(IDictionary<string, object> editorValue, PreValueCollection currentValue) { //the values from the editor will be min/max fieds and we need to format to json in one field var min = (editorValue.ContainsKey("min") ? editorValue["min"].ToString() : "0").TryConvertTo<int>(); var max = (editorValue.ContainsKey("max") ? editorValue["max"].ToString() : "0").TryConvertTo<int>(); var json = JObject.FromObject(new {Minimum = min.Success ? min.Result : 0, Maximum = max.Success ? max.Result : 0}); return new Dictionary<string, PreValue> { { "0", new PreValue(json.ToString(Formatting.None)) } }; }
public override IEnumerable<ValidationResult> Validate(object value, string config, PreValueCollection preValues, PropertyEditor editor) { if (value != null && value.ToString() != string.Empty) { var result = value.TryConvertTo<int>(); if (result.Success == false) { yield return new ValidationResult("The value " + value + " is not a valid integer", new[] { "value" }); } } }
public override IEnumerable<ValidationResult> Validate(object value, string config, PreValueCollection preValues, PropertyEditor editor) { var asString = value.ToString(); var emailVal = new EmailAddressAttribute(); if (emailVal.IsValid(asString) == false) { //TODO: localize these! yield return new ValidationResult("Email is invalid", new[] { "value" }); } }
public override IEnumerable<ValidationResult> Validate(object value, string config, PreValueCollection preValues, PropertyEditor editor) { //TODO: localize these! if (config.IsNullOrWhiteSpace() == false && value != null) { var asString = value.ToString(); var regex = new Regex(config); if (regex.IsMatch(asString) == false) { yield return new ValidationResult("Value is invalid, it does not match the correct pattern", new[] { "value" }); } } }
private bool HasPrevalues(PreValueCollection preVals) { if (preVals.PreValuesAsDictionary["crops"] == null || preVals.PreValuesAsDictionary["crops"].Value.IsNullOrWhiteSpace()) { return false; } try { var array = JsonConvert.DeserializeObject<JArray>(preVals.PreValuesAsDictionary["crops"].Value); return array.Count > 0; } catch (Exception) { return false; } }
/// <summary> /// Performs the validation /// </summary> /// <param name="value"></param> /// <param name="config">Can be a json formatted string containing properties: 'delimiter' and 'pattern'</param> /// <param name="preValues">The current pre-values stored for the data type</param> /// <param name="editor"></param> /// <returns></returns> public override IEnumerable<ValidationResult> Validate(object value, string config, PreValueCollection preValues, PropertyEditor editor) { //TODO: localize these! if (value != null) { var delimiter = ","; Regex regex = null; if (config.IsNullOrWhiteSpace() == false) { var json = JsonConvert.DeserializeObject<JObject>(config); if (json["delimiter"] != null) { delimiter = json["delimiter"].ToString(); } if (json["pattern"] != null) { var regexPattern = json["pattern"].ToString(); regex = new Regex(regexPattern); } } var stringVal = value.ToString(); var split = stringVal.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries); for (var i = 0; i < split.Length; i++) { var s = split[i]; //next if we have a regex statement validate with that if (regex != null) { if (regex.IsMatch(s) == false) { yield return new ValidationResult("The item at index " + i + " did not match the expression " + regex, new[] { //make the field name called 'value0' where 0 is the index "value" + i }); } } } } }
public override IEnumerable<ValidationResult> Validate(object value, string config, PreValueCollection preValues, PropertyEditor editor) { //TODO: localize these! if (value == null) { yield return new ValidationResult("Value cannot be null", new[] {"value"}); } else { var asString = value.ToString(); if (asString.IsNullOrWhiteSpace()) { yield return new ValidationResult("Value cannot be empty", new[] { "value" }); } } }
public IEnumerable<ValidationResult> Validate(object value, PreValueCollection preValues, PropertyEditor editor) { //don't validate if empty if (value == null || value.ToString().IsNullOrWhiteSpace()) { yield break; } DateTime dt; if (DateTime.TryParse(value.ToString(), out dt) == false) { yield return new ValidationResult(string.Format("The string value {0} cannot be parsed into a DateTime", value), new[] { //we only store a single value for this editor so the 'member' or 'field' // we'll associate this error with will simply be called 'value' "value" }); } }
public static void ConvertPreValueCollectionFromV011(PreValueCollection preValueCollection) { if (preValueCollection == null) { return; } var persistedPreValuesAsDictionary = preValueCollection.AsPreValueDictionary(); // do we have a "docTypeGuid" prevalue and no "contentTypes" prevalue? if (persistedPreValuesAsDictionary.ContainsKey("docTypeGuid") == false || persistedPreValuesAsDictionary.ContainsKey(ContentTypesPreValueKey)) { // the prevalues are already in >v0.1.1 format return; } // attempt to parse the doc type guid Guid guid; if (Guid.TryParse(persistedPreValuesAsDictionary["docTypeGuid"], out guid) == false) { // this shouldn't happen... but just in case. return; } // find the content type var contentType = ApplicationContext.Current.Services.ContentTypeService.GetAllContentTypes().FirstOrDefault(c => c.Key == guid); if (contentType == null) { return; } // add a prevalue in the format expected by the new (>0.1.1) content type picker/configurator preValueCollection.PreValuesAsDictionary[ContentTypesPreValueKey] = new PreValue( string.Format(@"[{{""ncAlias"": ""{0}"", ""ncTabAlias"": ""{1}"", ""nameTemplate"": ""{2}"", }}]", contentType.Alias, persistedPreValuesAsDictionary["tabAlias"], persistedPreValuesAsDictionary["nameTemplate"] ) ); }
internal ArchetypeModel DeserializeJsonToArchetype(string sourceJson, PreValueCollection dataTypePreValues) { try { var archetype = JsonConvert.DeserializeObject<ArchetypeModel>(sourceJson, _jsonSettings); try { // Get list of configured properties and their types and map them to the deserialized archetype model var preValue = GetArchetypePreValueFromPreValuesCollection(dataTypePreValues); RetrieveAdditionalProperties(ref archetype, preValue); } catch (Exception ex) { } return archetype; } catch { return new ArchetypeModel(); } }
public IEnumerable<ValidationResult> Validate(object value, PreValueCollection preValues, PropertyEditor editor) { //now check the file type var asJson = value as JObject; if (asJson == null) yield break; if (asJson["selectedFiles"] == null) yield break; var fileNames = asJson["selectedFiles"].ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var fileName in fileNames) { if (ValidateFileExtension(fileName) == false) { yield return new ValidationResult(ui.Text("errors", "dissallowedMediaType"), new[] { //we only store a single value for this editor so the 'member' or 'field' // we'll associate this error with will simply be called 'value' "value" }); } } }
/// <summary> /// Need to format the delimited posted string to individual values /// </summary> /// <param name="editorValue"></param> /// <param name="currentValue"></param> /// <returns> /// A string/string dictionary since all values that need to be persisted in the database are strings. /// </returns> /// <remarks> /// This is mostly because we want to maintain compatibility with v6 drop down property editors that store their prevalues in different db rows. /// </remarks> public override IDictionary<string, PreValue> ConvertEditorToDb(IDictionary<string, object> editorValue, PreValueCollection currentValue) { var val = editorValue["items"] as JArray; var result = new Dictionary<string, PreValue>(); if (val == null) { return result; } try { var index = 0; //get all values in the array that are not empty foreach (var item in val.OfType<JObject>() .Where(jItem => jItem["value"] != null) .Select(jItem => new { idAsString = jItem["id"] == null ? "0" : jItem["id"].ToString(), valAsString = jItem["value"].ToString() }) .Where(x => x.valAsString.IsNullOrWhiteSpace() == false)) { var id = 0; int.TryParse(item.idAsString, out id); result.Add(index.ToInvariantString(), new PreValue(id, item.valAsString)); index++; } } catch (Exception ex) { LogHelper.Error<ValueListPreValueEditor>("Could not deserialize the posted value: " + val, ex); } return result; }
public void DropDownPreValueEditor_Format_Data_For_Editor() { var defaultVals = new Dictionary<string, object>(); var persisted = new PreValueCollection(new Dictionary<string, PreValue> { {"item1", new PreValue(1, "Item 1")}, {"item2", new PreValue(2, "Item 2")}, {"item3", new PreValue(3, "Item 3")} }); var editor = new ValueListPreValueEditor(); var result = editor.ConvertDbToEditor(defaultVals, persisted); Assert.AreEqual(1, result.Count); Assert.IsTrue(result.ContainsKey("items")); var items = result["items"] as IDictionary<int, string>; Assert.IsNotNull(items); Assert.AreEqual("Item 1", items[1]); Assert.AreEqual("Item 2", items[2]); Assert.AreEqual("Item 3", items[3]); }
/// <summary> /// Take the posted values and convert them to a semi-colon separated list so that its backwards compatible /// </summary> /// <param name="editorValue"></param> /// <param name="currentValue"></param> /// <returns></returns> public override IDictionary<string, PreValue> ConvertEditorToDb(IDictionary<string, object> editorValue, PreValueCollection currentValue) { var result = base.ConvertEditorToDb(editorValue, currentValue); //this should just be a dictionary of values, we want to re-format this so that it is just one value in the dictionary that is // semi-colon delimited var values = result.Select(item => item.Value.Value).ToList(); result.Clear(); result.Add("thumbs", new PreValue(string.Join(";", values))); return result; }
/// <summary> /// Format the persisted value to work with our multi-val editor. /// </summary> /// <param name="defaultPreVals"></param> /// <param name="persistedPreVals"></param> /// <returns></returns> public override IDictionary<string, object> ConvertDbToEditor(IDictionary<string, object> defaultPreVals, PreValueCollection persistedPreVals) { var result = new Dictionary<string, object>(); //the pre-values just take up one field with a semi-colon delimiter so we'll just parse var dictionary = persistedPreVals.FormatAsDictionary(); if (dictionary.Any()) { //there should only be one val var delimited = dictionary.First().Value.Value.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries); for (var index = 0; index < delimited.Length; index++) { result.Add(index.ToInvariantString(), delimited[index]); } } //the items list will be a dictionary of it's id -> value we need to use the id for persistence for backwards compatibility return new Dictionary<string, object> { { "items", result } }; }
private ArchetypePreValue GetArchetypePreValueFromPreValuesCollection(PreValueCollection dataTypePreValues) { var preValueAsString = dataTypePreValues.PreValuesAsDictionary.First().Value.Value; var preValue = JsonConvert.DeserializeObject<ArchetypePreValue>(preValueAsString, _jsonSettings); return preValue; }
/// <summary> /// Validates the object with the resolved ValueValidator found for this type /// </summary> /// <param name="value"></param> /// <param name="preValues">The current pre-values stored for the data type</param> /// <param name="editor">The property editor instance that we are validating for</param> /// <returns></returns> public IEnumerable<ValidationResult> Validate(object value, PreValueCollection preValues, PropertyEditor editor) { return ValidatorInstance.Validate(value, Config, preValues, editor); }
/// <summary> /// A method to format the posted values from the editor to the values to be persisted /// </summary> /// <param name="editorValue"></param> /// <param name="currentValue"> /// The current value that has been persisted to the database for this pre-value editor. This value may be usesful for /// how the value then get's deserialized again to be re-persisted. In most cases it will probably not be used. /// </param> /// <returns></returns> /// <remarks> /// By default this will just return the Posted editorValue. /// /// This can be overridden if perhaps you have a comma delimited string posted value but want to convert those to individual rows, or to convert /// a json structure to multiple rows. /// </remarks> public virtual IDictionary<string, PreValue> ConvertEditorToDb(IDictionary<string, object> editorValue, PreValueCollection currentValue) { //convert to a string based value to be saved in the db return editorValue.ToDictionary(x => x.Key, x => new PreValue(x.Value == null ? null : x.Value.ToString())); }
/// <summary> /// This can be used to re-format the currently saved pre-values that will be passed to the editor, /// by default this returns the merged default and persisted pre-values. /// </summary> /// <param name="defaultPreVals"> /// The default/static pre-vals for the property editor /// </param> /// <param name="persistedPreVals"> /// The persisted pre-vals for the property editor /// </param> /// <returns></returns> /// <remarks> /// This is generally not going to be used by anything unless a property editor wants to change the merging /// functionality or needs to convert some legacy persisted data, or convert the string values to strongly typed values in json (i.e. booleans) /// /// IMPORTANT! When using this method the default pre values dictionary should not be modified which would change the property editor's global /// singleton pre-values! /// </remarks> public virtual IDictionary<string, object> ConvertDbToEditor(IDictionary<string, object> defaultPreVals, PreValueCollection persistedPreVals) { //we'll make a copy since we'll merge into the defaults - but we don't want to overwrite the global singleton ones passed in! var defaultPreValCopy = new Dictionary<string, object>(); if (defaultPreVals != null) { defaultPreValCopy = new Dictionary<string, object>(defaultPreVals); } if (persistedPreVals.IsDictionaryBased) { //we just need to merge the dictionaries now, the persisted will replace default. foreach (var item in persistedPreVals.PreValuesAsDictionary) { //The persisted dictionary contains values of type PreValue which contain the ID and the Value, we don't care // about the Id, just the value so ignore the id. defaultPreValCopy[item.Key] = item.Value.Value; } //now we're going to try to see if any of the values are JSON, if they are we'll convert them to real JSON objects // so they can be consumed as real json in angular! ConvertItemsToJsonIfDetected(defaultPreValCopy); return defaultPreValCopy; } //it's an array so need to format it var result = new Dictionary<string, object>(); var asArray = persistedPreVals.PreValuesAsArray.ToArray(); for (var i = 0; i < asArray.Length; i++) { //each item is of type PreValue but we don't want the ID, just the value so ignore the ID result.Add(i.ToInvariantString(), asArray[i].Value); } //now we're going to try to see if any of the values are JSON, if they are we'll convert them to real JSON objects // so they can be consumed as real json in angular! ConvertItemsToJsonIfDetected(result); return result; }
public IEnumerable<ValidationResult> Validate(object value, PreValueCollection preValues, PropertyEditor editor) { return Validate(value, null, preValues, editor); }
/// <summary> /// Performs the validation against the value /// </summary> /// <param name="value"> /// Depending on what is being validated, this value can be a json structure (JObject, JArray, etc...) representing an editor's model, it could be a single /// string representing an editor's model. /// </param> /// <param name="config"> /// An object that is used to configure the validator. An example could be a regex /// expression if the validator was a regex validator. This is defined in the manifest along with /// the definition of the validator. /// </param> /// <param name="preValues">The current pre-values stored for the data type</param> /// <param name="editor">The property editor instance that is being validated</param> /// <returns> /// Returns a list of validation results. If a result does not have a field name applied to it then then we assume that /// the validation message applies to the entire property type being validated. If there is a field name applied to a /// validation result we will try to match that field name up with a field name on the item itself. /// </returns> public abstract IEnumerable<ValidationResult> Validate(object value, string config, PreValueCollection preValues, PropertyEditor editor);