/// <summary> ///Dynamic value lists override static ones: /// * If a dynamic value list is null then hard coded ValueList is enforced if it is specified; /// * If a dynamic list is non-null then it is enforced if it is not blank, otherwise nothing is checked; /// Therefore: you may return an empty non-null dynamic list to prevent application of ValueList check for specific field/target /// </summary> protected virtual Exception CheckValueList(string targetName, Schema.FieldDef fdef, FieldAttribute atr, object value) { //try to obtain dynamic value list var dynValueList = GetDynamicFieldValueList(fdef, targetName, null); if (dynValueList != null)//check dynamic list is supplied { if (dynValueList.Count == 0) { return(null); //Nothing to check against; this is used to return empty list to override ValueList list } var fv = value.ToString(); if (!dynValueList.ContainsKey(fv)) { return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_IS_NOT_IN_LIST_ERROR.Args(fv.TakeFirstChars(9, "..")))); } } else if (atr.HasValueList)//check ValueList dictionary { var parsed = atr.ParseValueList(); var fv = value.ToString(); if (!parsed.ContainsKey(fv)) { return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_IS_NOT_IN_LIST_ERROR.Args(fv.TakeFirstChars(9, "..")))); } } return(null); }
protected virtual Exception CheckValueList(string targetName, Schema.FieldDef fdef, FieldAttribute atr, object value) { if (atr.HasValueList)//check dictionary { var parsed = atr.ParseValueList(); if (isSimpleKeyStringMap(parsed)) { var fv = value.ToString(); if (!parsed.ContainsKey(fv)) { return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_IS_NOT_IN_LIST_ERROR.Args(fv.TakeFirstChars(16, "..")))); } } } //check dynamic value list var dynValueList = GetDynamicFieldValueList(fdef, targetName, null); if (dynValueList != null)//check dictionary { var fv = value.ToString(); if (!dynValueList.ContainsKey(fv)) { return(new FieldValidationException(Schema.DisplayName, fdef.Name, StringConsts.CRUD_FIELD_VALUE_IS_NOT_IN_LIST_ERROR.Args(fv.TakeFirstChars(16, "..")))); } } return(null); }
private static void inheritAttribute(FieldAttribute parent, FieldAttribute self, string callSite) { //merge attributes from parent into self prop by prop foreach(var pi in ALL_PROPS) { if (pi.Name==nameof(MetadataContent)) { if (self.MetadataContent.IsNullOrWhiteSpace()) self.MetadataContent = parent.MetadataContent; else if (parent.MetadataContent.IsNotNullOrWhiteSpace()) { //merge var conf1 = ParseMetadataContent(parent.MetadataContent, callSite); var conf2 = ParseMetadataContent(self.MetadataContent, callSite); var merged = new LaconicConfiguration(); merged.CreateFromMerge(conf1, conf2); self.MetadataContent = merged.SaveToString(); } continue; }//metadata merge if (pi.Name==nameof(ValueList)) { if (!self.HasValueList) self.ValueList = parent.ValueList; else if (parent.HasValueList) { //merge var vl1 = parent.ParseValueList(true); var vl2 = self.ParseValueList(true); vl2.Append(vl1);//merge missing in self from parent //remove all that start with REMOVE // to remove a key include an override with: `keyABC: #del#` (item keyed on `keyABC` will be removed) const string DELETE = "#del#"; vl2.Where(kvp => kvp.Value.AsString().EqualsOrdIgnoreCase(DELETE)) .ToArray() .ForEach( kvp => vl2.Remove(kvp.Key) ); self.ValueList = BuildValueListString(vl2);//reconstitute jsonmap back into string } continue; } if (self.PropertyWasAssigned(pi.Name)) continue;//was overridden pi.SetValue(self, pi.GetValue(parent));//set value } }