private void DiscoverRecordFields(Type recordType) { if (!IsDynamicObject) // recordType != typeof(ExpandoObject)) { JSONRecordFieldConfigurations.Clear(); if (ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any()).Any()) { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any())) { var obj = new ChoJSONRecordFieldConfiguration(pd.Name, pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().First()); obj.FieldType = pd.PropertyType; JSONRecordFieldConfigurations.Add(obj); } } else { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { var obj = new ChoJSONRecordFieldConfiguration(pd.Name, (string)null); obj.FieldType = pd.PropertyType; JSONRecordFieldConfigurations.Add(obj); } } } }
internal ChoJSONRecordFieldConfiguration GetFieldConfiguration(string propertyName, ChoJSONRecordFieldAttribute attr = null, Attribute[] otherAttrs = null, PropertyDescriptor pd = null, string fqm = null, Type subType = null) { if (subType != null) { MapRecordFieldsForType(subType); var fc = new ChoJSONRecordFieldConfiguration(propertyName, attr, otherAttrs); fc.PropertyDescriptor = pd; fc.DeclaringMember = fqm; AddFieldForType(subType, fc); return(fc); } else { if (!JSONRecordFieldConfigurations.Any(fc => fc.Name == propertyName)) { JSONRecordFieldConfigurations.Add(new ChoJSONRecordFieldConfiguration(propertyName, attr, otherAttrs)); } var nfc = JSONRecordFieldConfigurations.First(fc => fc.Name == propertyName); nfc.PropertyDescriptor = pd; nfc.DeclaringMember = fqm; return(nfc); } }
private ChoJSONWriter <T> WithField(string name, Type fieldType = null, ChoFieldValueTrimOption fieldValueTrimOption = ChoFieldValueTrimOption.Trim, string fieldName = null, Func <object, object> valueConverter = null, object defaultValue = null, object fallbackValue = null, string fullyQualifiedMemberName = null, string formatText = null, string nullValue = null) { if (!name.IsNullOrEmpty()) { if (!_clearFields) { ClearFields(); Configuration.MapRecordFields(Configuration.RecordType); } string fnTrim = name.NTrim(); ChoJSONRecordFieldConfiguration fc = null; PropertyDescriptor pd = null; if (Configuration.JSONRecordFieldConfigurations.Any(o => o.Name == fnTrim)) { fc = Configuration.JSONRecordFieldConfigurations.Where(o => o.Name == fnTrim).First(); Configuration.JSONRecordFieldConfigurations.Remove(fc); } else { pd = ChoTypeDescriptor.GetNestedProperty(typeof(T), fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } var nfc = new ChoJSONRecordFieldConfiguration(fnTrim, (string)null) { FieldType = fieldType, FieldValueTrimOption = fieldValueTrimOption, FieldName = fieldName, ValueConverter = valueConverter, DefaultValue = defaultValue, FallbackValue = fallbackValue, FormatText = formatText, NullValue = nullValue }; if (fullyQualifiedMemberName.IsNullOrWhiteSpace()) { nfc.PropertyDescriptor = fc != null ? fc.PropertyDescriptor : pd; nfc.DeclaringMember = fc != null ? fc.DeclaringMember : fullyQualifiedMemberName; } else { pd = ChoTypeDescriptor.GetNestedProperty(typeof(T), fullyQualifiedMemberName); nfc.PropertyDescriptor = pd; nfc.DeclaringMember = fullyQualifiedMemberName; } if (pd != null) { if (nfc.FieldType == null) { nfc.FieldType = pd.PropertyType; } } Configuration.JSONRecordFieldConfigurations.Add(nfc); } return(this); }
public ChoContractResolverJsonConverter(ChoJSONRecordFieldConfiguration fc, CultureInfo culture, Type objType, ChoObjectValidationMode validationMode, MemberInfo mi) { _fc = fc; _culture = culture; _objType = objType; _validationMode = validationMode; _mi = mi; }
private string CleanFieldValue(ChoJSONRecordFieldConfiguration config, Type fieldType, string fieldValue) { if (fieldValue == null) { return(fieldValue); } ChoFieldValueTrimOption fieldValueTrimOption = ChoFieldValueTrimOption.Trim; if (config.FieldValueTrimOption == null) { //if (fieldType == typeof(string)) // fieldValueTrimOption = ChoFieldValueTrimOption.None; } else { fieldValueTrimOption = config.FieldValueTrimOption.Value; } switch (fieldValueTrimOption) { case ChoFieldValueTrimOption.Trim: fieldValue = fieldValue.Trim(); break; case ChoFieldValueTrimOption.TrimStart: fieldValue = fieldValue.TrimStart(); break; case ChoFieldValueTrimOption.TrimEnd: fieldValue = fieldValue.TrimEnd(); break; } if (config.Size != null) { if (fieldValue.Length > config.Size.Value) { if (!config.Truncate) { throw new ChoParserException("Incorrect field value length found for '{0}' member [Expected: {1}, Actual: {2}].".FormatString(config.FieldName, config.Size.Value, fieldValue.Length)); } else { fieldValue = fieldValue.Substring(0, config.Size.Value); } } } if (fieldValue.StartsWith(@"""") && fieldValue.EndsWith(@"""")) { fieldValue = fieldValue.Substring(1, fieldValue.Length - 2); } return(System.Net.WebUtility.HtmlDecode(fieldValue)); }
internal bool IsArray(ChoJSONRecordFieldConfiguration fc) { if (fc == null || fc.IsArray == null) { return(DefaultArrayHandling == null ? false : DefaultArrayHandling.Value); } else { return(fc.IsArray.Value); } }
public ChoJSONRecordConfiguration Map <T, TField>(Expression <Func <T, TField> > field, Action <ChoJSONRecordFieldConfigurationMap> mapper) { var subType = field.GetReflectedType(); var fn = field.GetMemberName(); var pd = field.GetPropertyDescriptor(); var fqm = field.GetFullyQualifiedMemberName(); ChoJSONRecordFieldConfiguration cf = GetFieldConfiguration(fn, pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().FirstOrDefault(), pd.Attributes.OfType <Attribute>().ToArray(), pd, fqm, null /* subType == typeof(T) ? null : subType */); mapper?.Invoke(new ChoJSONRecordFieldConfigurationMap(cf)); return(this); }
//public ChoJSONReader<T> WithFields<TClass, TField>(params Expression<Func<TClass, TField>>[] fields) //{ // if (fields != null) // { // foreach (var field in fields) // return WithField<TClass>(field); // } // return this; //} public ChoJSONReader <T> WithFields(params string[] fieldsNames) { string fnTrim = null; if (!fieldsNames.IsNullOrEmpty()) { PropertyDescriptor pd = null; ChoJSONRecordFieldConfiguration fc = null; foreach (string fn in fieldsNames) { if (fn.IsNullOrEmpty()) { continue; } if (!_clearFields) { ClearFields(); Configuration.MapRecordFields(Configuration.RecordType); } fnTrim = fn.NTrim(); if (Configuration.JSONRecordFieldConfigurations.Any(o => o.Name == fnTrim)) { fc = Configuration.JSONRecordFieldConfigurations.Where(o => o.Name == fnTrim).First(); Configuration.JSONRecordFieldConfigurations.Remove(Configuration.JSONRecordFieldConfigurations.Where(o => o.Name == fnTrim).First()); } else { pd = ChoTypeDescriptor.GetProperty(typeof(T), fn); } var nfc = new ChoJSONRecordFieldConfiguration(fnTrim, (string)null); nfc.PropertyDescriptor = fc != null ? fc.PropertyDescriptor : pd; nfc.DeclaringMember = fc != null ? fc.DeclaringMember : null; if (pd != null) { if (nfc.FieldType == null) { nfc.FieldType = pd.PropertyType; } } Configuration.JSONRecordFieldConfigurations.Add(nfc); } } return(this); }
public void Write(IDataReader dr) { ChoGuard.ArgumentNotNull(dr, "DataReader"); if (Configuration.UseJSONSerialization) { Write(dr); return; } DataTable schemaTable = dr.GetSchemaTable(); dynamic expando = new ExpandoObject(); var expandoDic = (IDictionary <string, object>)expando; //int ordinal = 0; if (Configuration.JSONRecordFieldConfigurations.IsNullOrEmpty()) { string colName = null; Type colType = null; int startIndex = 0; int fieldLength = 0; foreach (DataRow row in schemaTable.Rows) { colName = row["ColumnName"].CastTo <string>(); colType = row["DataType"] as Type; //if (!colType.IsSimple()) continue; var obj = new ChoJSONRecordFieldConfiguration(colName, jsonPath: null); Configuration.JSONRecordFieldConfigurations.Add(obj); startIndex += fieldLength; } } var ordinals = Configuration.JSONRecordFieldConfigurations.ToDictionary(c => c.Name, c => dr.HasColumn(c.Name) ? dr.GetOrdinal(c.Name) : -1); while (dr.Read()) { expandoDic.Clear(); foreach (var fc in ordinals) { expandoDic.Add(fc.Key, fc.Value == -1 ? null : dr[fc.Value]); } Write(expando); } }
public void Write(DataTable dt) { ChoGuard.ArgumentNotNull(dt, "DataTable"); if (Configuration.UseJSONSerialization) { Write(dt); return; } DataTable schemaTable = dt; dynamic expando = new ExpandoObject(); var expandoDic = (IDictionary <string, object>)expando; if (Configuration.JSONRecordFieldConfigurations.IsNullOrEmpty()) { string colName = null; Type colType = null; int startIndex = 0; int fieldLength = 0; foreach (DataColumn col in schemaTable.Columns) { colName = col.ColumnName; colType = col.DataType; //if (!colType.IsSimple()) continue; var obj = new ChoJSONRecordFieldConfiguration(colName, jsonPath: null); Configuration.JSONRecordFieldConfigurations.Add(obj); startIndex += fieldLength; } } Configuration.RootName = dt.TableName.IsNullOrWhiteSpace() ? null : dt.TableName; foreach (DataRow row in dt.Rows) { expandoDic.Clear(); foreach (var fc in Configuration.JSONRecordFieldConfigurations) { expandoDic.Add(fc.Name, row[fc.Name] == DBNull.Value ? null : row[fc.Name]); } Write(expando); } }
internal void AddFieldForType(Type rt, ChoJSONRecordFieldConfiguration rc) { if (rt == null || rc == null) { return; } if (!JSONRecordFieldConfigurationsForType.ContainsKey(rt)) { JSONRecordFieldConfigurationsForType.Add(rt, new Dictionary <string, ChoJSONRecordFieldConfiguration>(StringComparer.InvariantCultureIgnoreCase)); } if (JSONRecordFieldConfigurationsForType[rt].ContainsKey(rc.Name)) { JSONRecordFieldConfigurationsForType[rt][rc.Name] = rc; } else { JSONRecordFieldConfigurationsForType[rt].Add(rc.Name, rc); } }
public void Write(IDataReader dr) { ChoGuard.ArgumentNotNull(dr, "DataReader"); DataTable schemaTable = dr.GetSchemaTable(); dynamic expando = new ExpandoObject(); var expandoDic = (IDictionary <string, object>)expando; //int ordinal = 0; if (Configuration.JSONRecordFieldConfigurations.IsNullOrEmpty()) { string colName = null; Type colType = null; int startIndex = 0; int fieldLength = 0; foreach (DataRow row in schemaTable.Rows) { colName = row["ColumnName"].CastTo <string>(); colType = row["DataType"] as Type; //if (!colType.IsSimple()) continue; var obj = new ChoJSONRecordFieldConfiguration(colName, jsonPath: null); Configuration.JSONRecordFieldConfigurations.Add(obj); startIndex += fieldLength; } } while (dr.Read()) { expandoDic.Clear(); foreach (var fc in Configuration.JSONRecordFieldConfigurations) { expandoDic.Add(fc.Name, dr[fc.Name]); } Write(expando); } }
private bool FillRecord(object rec, Tuple <long, JObject> pair) { long lineNo; JObject node; JToken jToken = null; lineNo = pair.Item1; node = pair.Item2; fJObjects = null; fieldValue = null; fieldConfig = null; pi = null; //IDictionary<string, object> dictValues = ToDictionary(node); foreach (KeyValuePair <string, ChoJSONRecordFieldConfiguration> kvp in Configuration.RecordFieldConfigurationsDict) { fieldValue = null; fieldConfig = kvp.Value; if (Configuration.PIDict != null) { Configuration.PIDict.TryGetValue(kvp.Key, out pi); } //fieldValue = dictValues[kvp.Key]; if (!kvp.Value.JSONPath.IsNullOrWhiteSpace()) { jToken = node.SelectToken(kvp.Value.JSONPath); if (jToken == null) { if (Configuration.ColumnCountStrict) { throw new ChoParserException("No matching '{0}' field found.".FormatString(fieldConfig.FieldName)); } } } else { if (!node.TryGetValue(kvp.Key, StringComparison.CurrentCultureIgnoreCase, out jToken)) { if (Configuration.ColumnCountStrict) { throw new ChoParserException("No matching '{0}' field found.".FormatString(fieldConfig.FieldName)); } } } if (rec is ExpandoObject) { if (kvp.Value.FieldType == null) { fieldValue = jToken; } else { fieldValue = jToken != null?jToken.ToObject(kvp.Value.FieldType) : null; } } else { if (pi != null) { kvp.Value.FieldType = pi.PropertyType; } else { kvp.Value.FieldType = typeof(string); } fieldValue = jToken != null?jToken.ToObject(kvp.Value.FieldType) : null; } if (!(fieldValue is ICollection)) { if (fieldValue is string) { fieldValue = CleanFieldValue(fieldConfig, kvp.Value.FieldType, fieldValue as string); } } if (!RaiseBeforeRecordFieldLoad(rec, pair.Item1, kvp.Key, ref fieldValue)) { continue; } try { bool ignoreFieldValue = fieldConfig.IgnoreFieldValue(fieldValue); if (ignoreFieldValue) { fieldValue = fieldConfig.IsDefaultValueSpecified ? fieldConfig.DefaultValue : null; } if (Configuration.IsDynamicObject) { var dict = rec as IDictionary <string, Object>; dict.ConvertNSetMemberValue(kvp.Key, kvp.Value, ref fieldValue, Configuration.Culture); if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.MemberLevel) == ChoObjectValidationMode.MemberLevel) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } } else { if (pi != null) { rec.ConvertNSetMemberValue(kvp.Key, kvp.Value, ref fieldValue, Configuration.Culture); } else { throw new ChoMissingRecordFieldException("Missing '{0}' property in {1} type.".FormatString(kvp.Key, ChoType.GetTypeName(rec))); } if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.MemberLevel) == ChoObjectValidationMode.MemberLevel) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } } if (!RaiseAfterRecordFieldLoad(rec, pair.Item1, kvp.Key, fieldValue)) { return(false); } } catch (ChoParserException) { throw; } catch (ChoMissingRecordFieldException) { if (Configuration.ThrowAndStopOnMissingField) { throw; } } catch (Exception ex) { ChoETLFramework.HandleException(ex); if (fieldConfig.ErrorMode == ChoErrorMode.ThrowAndStop) { throw; } try { if (Configuration.IsDynamicObject) { var dict = rec as IDictionary <string, Object>; if (dict.SetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (dict.SetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } else if (pi != null) { if (rec.SetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (rec.SetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } catch (Exception innerEx) { if (ex == innerEx.InnerException) { if (fieldConfig.ErrorMode == ChoErrorMode.IgnoreAndContinue) { continue; } else { if (!RaiseRecordFieldLoadError(rec, pair.Item1, kvp.Key, fieldValue, ex)) { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } } else { throw new ChoReaderException("Failed to assign '{0}' fallback value to '{1}' field.".FormatString(fieldValue, fieldConfig.FieldName), innerEx); } } } } return(true); }
private bool ToText(long index, object rec, out string recText) { if (typeof(IChoScalarObject).IsAssignableFrom(Configuration.RecordType)) { rec = Activator.CreateInstance(Configuration.RecordType, rec); } if (!Configuration.IsDynamicObject) { if (rec.ToTextIfCustomSerialization(out recText)) { return(true); } //Check if KVP object if (rec.GetType().IsKeyValueType()) { recText = SerializeObject(rec); return(true); } } recText = null; if (rec == null) { if (Configuration.NullValueHandling == ChoNullValueHandling.Ignore) { return(false); } else if (Configuration.NullValueHandling == ChoNullValueHandling.Default) { rec = Activator.CreateInstance(Configuration.RecordType); } else { recText = "{{{0}}}".FormatString(Configuration.Formatting == Formatting.Indented ? Configuration.EOLDelimiter : String.Empty); return(true); } } StringBuilder msg = new StringBuilder(); object fieldValue = null; string fieldText = null; ChoJSONRecordFieldConfiguration fieldConfig = null; if (Configuration.ColumnCountStrict) { CheckColumnsStrict(rec); } //bool firstColumn = true; PropertyInfo pi = null; bool isFirst = true; object rootRec = rec; msg.AppendFormat("{{{0}", Configuration.Formatting == Formatting.Indented ? Configuration.EOLDelimiter : String.Empty); foreach (KeyValuePair <string, ChoJSONRecordFieldConfiguration> kvp in Configuration.RecordFieldConfigurationsDict) { fieldConfig = kvp.Value; fieldValue = null; fieldText = String.Empty; if (Configuration.PIDict != null) { Configuration.PIDict.TryGetValue(kvp.Key, out pi); } rec = GetDeclaringRecord(kvp.Value.DeclaringMember, rootRec); if (Configuration.ThrowAndStopOnMissingField) { if (Configuration.IsDynamicObject) { var dict = rec.ToDynamicObject() as IDictionary <string, Object>; if (!dict.ContainsKey(kvp.Key)) { throw new ChoMissingRecordFieldException("No matching property found in the object for '{0}' JSON node.".FormatString(fieldConfig.FieldName)); } } else { if (pi == null) { throw new ChoMissingRecordFieldException("No matching property found in the object for '{0}' JSON node.".FormatString(fieldConfig.FieldName)); } } } try { if (Configuration.IsDynamicObject) { IDictionary <string, Object> dict = rec.ToDynamicObject() as IDictionary <string, Object>; fieldValue = dict[kvp.Key]; // dict.GetValue(kvp.Key, Configuration.FileHeaderConfiguration.IgnoreCase, Configuration.Culture); if (kvp.Value.FieldType == null) { if (fieldValue == null) { kvp.Value.FieldType = typeof(string); } else { kvp.Value.FieldType = fieldValue.GetType(); } } } else { if (pi != null) { fieldValue = ChoType.GetPropertyValue(rec, pi); if (kvp.Value.FieldType == null) { kvp.Value.FieldType = pi.PropertyType; } } else { kvp.Value.FieldType = typeof(string); } } //Discover default value, use it if null if (fieldValue == null) { if (fieldConfig.IsDefaultValueSpecified) { fieldValue = fieldConfig.DefaultValue; } } if (!RaiseBeforeRecordFieldWrite(rec, index, kvp.Key, ref fieldValue)) { return(false); } if (fieldConfig.ValueConverter != null) { fieldValue = fieldConfig.ValueConverter(fieldValue); } else { rec.GetNConvertMemberValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue, true); } if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.ObjectLevel) == ChoObjectValidationMode.MemberLevel) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode, fieldValue); } if (!RaiseAfterRecordFieldWrite(rec, index, kvp.Key, fieldValue)) { return(false); } } catch (ChoParserException) { throw; } catch (ChoMissingRecordFieldException) { if (Configuration.ThrowAndStopOnMissingField) { throw; } } catch (Exception ex) { ChoETLFramework.HandleException(ref ex); if (fieldConfig.ErrorMode == ChoErrorMode.ThrowAndStop) { throw; } try { if (Configuration.IsDynamicObject) { var dict = rec.ToDynamicObject() as IDictionary <string, Object>; if (dict.GetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode, fieldValue); } else if (dict.GetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode, fieldValue); } else { var ex1 = new ChoWriterException($"Failed to write '{fieldValue}' value for '{fieldConfig.FieldName}' member.", ex); fieldValue = null; throw ex1; } } else if (pi != null) { if (rec.GetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (rec.GetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode, fieldValue); } else { var ex1 = new ChoWriterException($"Failed to write '{fieldValue}' value for '{fieldConfig.FieldName}' member.", ex); fieldValue = null; throw ex1; } } else { var ex1 = new ChoWriterException($"Failed to write '{fieldValue}' value for '{fieldConfig.FieldName}' member.", ex); fieldValue = null; throw ex1; } } catch (Exception innerEx) { if (ex == innerEx.InnerException) { if (fieldConfig.ErrorMode == ChoErrorMode.IgnoreAndContinue) { continue; } else { if (!RaiseRecordFieldWriteError(rec, index, kvp.Key, fieldText, ex)) { throw new ChoWriterException($"Failed to write '{fieldValue}' value of '{kvp.Key}' member.", ex); } } } else { throw new ChoWriterException("Failed to use '{0}' fallback value for '{1}' member.".FormatString(fieldValue, kvp.Key), innerEx); } } } bool isSimple = true; if (RaiseRecordFieldSerialize(rec, index, kvp.Key, ref fieldValue)) { if (isFirst) { msg.AppendFormat("{1}{0}", fieldValue.ToNString(), Configuration.Formatting == Formatting.Indented ? " " : String.Empty); } else { msg.AppendFormat(",{1}{2}{0}", fieldValue.ToNString(), Configuration.Formatting == Formatting.Indented ? Configuration.EOLDelimiter : String.Empty, Configuration.Formatting == Formatting.Indented ? " " : String.Empty); } } else { Type ft = fieldValue == null ? typeof(object) : fieldValue.GetType(); if (fieldValue == null) { fieldText = "null"; } else if (ft == typeof(string) || ft == typeof(char)) { fieldText = JsonConvert.SerializeObject(NormalizeFieldValue(kvp.Key, fieldValue.ToString(), kvp.Value.Size, kvp.Value.Truncate, false, GetFieldValueJustification(kvp.Value.FieldValueJustification, kvp.Value.FieldType), GetFillChar(kvp.Value.FillChar, kvp.Value.FieldType), false)); } else if (ft == typeof(DateTime)) { fieldText = JsonConvert.SerializeObject(fieldValue); } else if (ft.IsEnum) { fieldText = JsonConvert.SerializeObject(fieldValue); } else if (ft == typeof(ChoCurrency)) { fieldText = "\"{0}\"".FormatString(fieldValue.ToString()); } else if (ft == typeof(bool)) { fieldText = JsonConvert.SerializeObject(fieldValue); } else if (ft.IsNumeric()) { fieldText = fieldValue.ToString(); } else { isSimple = false; } if (isFirst) { msg.AppendFormat("{2}\"{0}\":{1}", fieldConfig.FieldName, isSimple ? " {0}".FormatString(fieldText) : Configuration.Formatting == Formatting.Indented ? SerializeObject(fieldValue, fieldConfig.UseJSONSerialization).Indent(1, " ") : SerializeObject(fieldValue, fieldConfig.UseJSONSerialization), Configuration.Formatting == Formatting.Indented ? " " : String.Empty); } else { msg.AppendFormat(",{2}{3}\"{0}\":{1}", fieldConfig.FieldName, isSimple ? " {0}".FormatString(fieldText) : Configuration.Formatting == Formatting.Indented ? SerializeObject(fieldValue, fieldConfig.UseJSONSerialization).Indent(1, " ") : SerializeObject(fieldValue, fieldConfig.UseJSONSerialization), Configuration.Formatting == Formatting.Indented ? Configuration.EOLDelimiter : String.Empty, Configuration.Formatting == Formatting.Indented ? " " : String.Empty); } } isFirst = false; } msg.AppendFormat("{0}}}", Configuration.Formatting == Formatting.Indented ? Configuration.EOLDelimiter : String.Empty); recText = msg.ToString(); return(true); }
public override void Validate(object state) { base.Validate(state); string[] fieldNames = null; JObject jObject = null; if (state is Tuple <long, JObject> ) { jObject = ((Tuple <long, JObject>)state).Item2; } else { fieldNames = state as string[]; } if (AutoDiscoverColumns && JSONRecordFieldConfigurations.Count == 0) { if (RecordType != null && !IsDynamicObject && /*&& RecordType != typeof(ExpandoObject)*/ ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any()).Any()) { long startIndex = 0; long size = 0; string jpath = null; ChoJSONRecordFieldAttribute attr = null; foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any())) { attr = ChoTypeDescriptor.GetPropetyAttribute <ChoJSONRecordFieldAttribute>(pd); var obj = new ChoJSONRecordFieldConfiguration(pd.Name, jpath); obj.FieldType = pd.PropertyType; JSONRecordFieldConfigurations.Add(obj); startIndex += size; } } else if (jObject != null) { Dictionary <string, ChoJSONRecordFieldConfiguration> dict = new Dictionary <string, ChoJSONRecordFieldConfiguration>(StringComparer.CurrentCultureIgnoreCase); string name = null; foreach (var attr in jObject.Properties()) { name = attr.Name; if (!dict.ContainsKey(name)) { dict.Add(name, new ChoJSONRecordFieldConfiguration(name, (string)null)); } else { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); } } foreach (ChoJSONRecordFieldConfiguration obj in dict.Values) { JSONRecordFieldConfigurations.Add(obj); } } else if (!fieldNames.IsNullOrEmpty()) { foreach (string fn in fieldNames) { var obj = new ChoJSONRecordFieldConfiguration(fn, (string)null); JSONRecordFieldConfigurations.Add(obj); } } } else { foreach (var fc in JSONRecordFieldConfigurations) { fc.ComplexJPathUsed = !(fc.JSONPath.IsNullOrWhiteSpace() || String.Compare(fc.FieldName, fc.JSONPath, true) == 0); } } if (JSONRecordFieldConfigurations.Count <= 0) { throw new ChoRecordConfigurationException("No record fields specified."); } //Validate each record field foreach (var fieldConfig in JSONRecordFieldConfigurations) { fieldConfig.Validate(this); } //Check field position for duplicate string[] dupFields = JSONRecordFieldConfigurations.GroupBy(i => i.Name) .Where(g => g.Count() > 1) .Select(g => g.Key).ToArray(); if (dupFields.Length > 0) { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(String.Join(",", dupFields))); } RecordFieldConfigurationsDict = JSONRecordFieldConfigurations.Where(i => !i.Name.IsNullOrWhiteSpace()).ToDictionary(i => i.Name); LoadNCacheMembers(JSONRecordFieldConfigurations); }
private bool FillRecord(object rec, Tuple <long, JObject> pair) { long lineNo; JObject node; JToken jToken = null; JToken[] jTokens = null; lineNo = pair.Item1; node = pair.Item2; fieldValue = null; fieldConfig = null; pi = null; //IDictionary<string, object> dictValues = ToDictionary(node); if (!Configuration.IsDynamicObject) { if (rec.FillIfCustomSerialization(pair.Item2)) { return(true); } if (FillIfKeyValueObject(rec, pair)) { return(true); } } foreach (KeyValuePair <string, ChoJSONRecordFieldConfiguration> kvp in Configuration.RecordFieldConfigurationsDict) { fieldValue = null; fieldConfig = kvp.Value; if (Configuration.PIDict != null) { Configuration.PIDict.TryGetValue(kvp.Key, out pi); } //fieldValue = dictValues[kvp.Key]; if (!kvp.Value.JSONPath.IsNullOrWhiteSpace()) { jTokens = node.SelectTokens(kvp.Value.JSONPath).ToArray(); jToken = jTokens.FirstOrDefault(); if (jToken == null) { if (Configuration.ColumnCountStrict) { throw new ChoParserException("No matching '{0}' field found.".FormatString(fieldConfig.FieldName)); } } } else { if (!node.TryGetValue(kvp.Key, StringComparison.CurrentCultureIgnoreCase, out jToken)) { if (Configuration.ColumnCountStrict) { throw new ChoParserException("No matching '{0}' field found.".FormatString(fieldConfig.FieldName)); } } } fieldValue = !jTokens.IsNullOrEmpty() ? (object)jTokens : jToken; if (!RaiseBeforeRecordFieldLoad(rec, pair.Item1, kvp.Key, ref fieldValue)) { continue; } if (Configuration.IsDynamicObject) //rec is ExpandoObject) { } else { if (pi != null) { kvp.Value.FieldType = pi.PropertyType; } else { kvp.Value.FieldType = typeof(string); } } if (fieldConfig.ValueConverter != null) { fieldValue = fieldConfig.ValueConverter(fieldValue); } else { if (fieldConfig.FieldType == null) { if (!fieldConfig.IsArray && fieldValue is JToken[]) { fieldValue = ((JToken[])fieldValue).FirstOrDefault(); if (fieldValue is JArray) { fieldValue = ((JArray)fieldValue).FirstOrDefault(); } } } else { if (!fieldConfig.FieldType.IsCollection() && fieldValue is JToken[]) { fieldValue = ((JToken[])fieldValue).FirstOrDefault(); //if (fieldValue is JArray) //{ // fieldValue = ((JArray)fieldValue).FirstOrDefault(); //} } } if (fieldConfig.FieldType == null || fieldConfig.FieldType == typeof(object) || fieldConfig.FieldType.GetItemType() == typeof(object)) { if (fieldValue is JToken) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fieldValue); } else { fieldValue = ToObject((JToken)fieldValue, null); } } else if (fieldValue is JToken[]) { List <object> arr = new List <object>(); foreach (var ele in (JToken[])fieldValue) { if (fieldConfig.ItemConverter != null) { arr.Add(fieldConfig.ItemConverter(ele)); } else { arr.Add(ToObject(ele, null)); } } fieldValue = arr.ToArray(); } } else if (fieldConfig.FieldType == typeof(string) || fieldConfig.FieldType.IsSimple()) { if (fieldValue is JToken[]) { fieldValue = ((JToken[])fieldValue).FirstOrDefault(); } if (fieldValue is JToken) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fieldValue); } else { fieldValue = ToObject((JToken)fieldValue, fieldConfig.FieldType); } } } //else if (fieldConfig.FieldType.IsCollection()) //{ // List<object> list = new List<object>(); // Type itemType = fieldConfig.FieldType.GetItemType().GetUnderlyingType(); // if (fieldValue is JToken) // { // if (fieldConfig.ItemConverter != null) // fieldValue = fieldConfig.ItemConverter(fieldValue); // else // fieldValue = ToObject((JToken)fieldValue, itemType); // } // else if (fieldValue is JToken[]) // { // foreach (var ele in (JToken[])fieldValue) // { // if (fieldConfig.ItemConverter != null) // list.Add(fieldConfig.ItemConverter(ele)); // else // { // fieldValue = ToObject(ele, itemType); // } // } // fieldValue = list.ToArray(); // } //} else { List <object> list = new List <object>(); Type itemType = fieldConfig.FieldType.GetUnderlyingType().GetItemType().GetUnderlyingType(); if (fieldValue is JToken) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fieldValue); } else { fieldValue = ToObject((JToken)fieldValue, itemType); } } else if (fieldValue is JToken[]) { var fi = ((JToken[])fieldValue).FirstOrDefault(); if (fi is JArray && !itemType.IsCollection()) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fi); } else { fieldValue = ToObject(fi, fieldConfig.FieldType); } } else { foreach (var ele in (JToken[])fieldValue) { if (fieldConfig.ItemConverter != null) { list.Add(fieldConfig.ItemConverter(ele)); } else { list.Add(ToObject(ele, itemType)); } } fieldValue = list.ToArray(); } } } } if (!(fieldValue is ICollection)) { if (fieldValue is string) { fieldValue = CleanFieldValue(fieldConfig, kvp.Value.FieldType, fieldValue as string); } else if (fieldValue is JValue) { if (((JValue)fieldValue).Value is string) { fieldValue = CleanFieldValue(fieldConfig, kvp.Value.FieldType, fieldValue.ToString()); } else { fieldValue = ((JValue)fieldValue).Value; } } } try { bool ignoreFieldValue = fieldConfig.IgnoreFieldValue(fieldValue); if (ignoreFieldValue) { fieldValue = fieldConfig.IsDefaultValueSpecified ? fieldConfig.DefaultValue : null; } if (Configuration.IsDynamicObject) { var dict = rec as IDictionary <string, Object>; dict.ConvertNSetMemberValue(kvp.Key, kvp.Value, ref fieldValue, Configuration.Culture); if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.MemberLevel) == ChoObjectValidationMode.MemberLevel) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } } else { if (pi != null) { rec.ConvertNSetMemberValue(kvp.Key, kvp.Value, ref fieldValue, Configuration.Culture); } else { throw new ChoMissingRecordFieldException("Missing '{0}' property in {1} type.".FormatString(kvp.Key, ChoType.GetTypeName(rec))); } if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.MemberLevel) == ChoObjectValidationMode.MemberLevel) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } } if (!RaiseAfterRecordFieldLoad(rec, pair.Item1, kvp.Key, fieldValue)) { return(false); } } catch (ChoParserException) { Reader.IsValid = false; throw; } catch (ChoMissingRecordFieldException) { Reader.IsValid = false; if (Configuration.ThrowAndStopOnMissingField) { throw; } } catch (Exception ex) { Reader.IsValid = false; ChoETLFramework.HandleException(ref ex); if (fieldConfig.ErrorMode == ChoErrorMode.ThrowAndStop) { throw; } try { if (Configuration.IsDynamicObject) { var dict = rec as IDictionary <string, Object>; if (dict.SetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (dict.SetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } else if (pi != null) { if (rec.SetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (rec.SetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } catch (Exception innerEx) { if (ex == innerEx.InnerException) { if (fieldConfig.ErrorMode == ChoErrorMode.IgnoreAndContinue) { continue; } else { if (!RaiseRecordFieldLoadError(rec, pair.Item1, kvp.Key, fieldValue, ex)) { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } } else { throw new ChoReaderException("Failed to assign '{0}' fallback value to '{1}' field.".FormatString(fieldValue, fieldConfig.FieldName), innerEx); } } } } return(true); }
internal ChoJSONRecordFieldConfigurationMap(ChoJSONRecordFieldConfiguration config) { _config = config; }
internal void WithField(string name, string jsonPath = null, Type fieldType = null, ChoFieldValueTrimOption fieldValueTrimOption = ChoFieldValueTrimOption.Trim, string fieldName = null, Func <object, object> valueConverter = null, Func <object, object> itemConverter = null, Func <object, object> customSerializer = null, object defaultValue = null, object fallbackValue = null, string fullyQualifiedMemberName = null, string formatText = null, bool?isArray = null, string nullValue = null, Type recordType = null, Type subRecordType = null, Func <JObject, Type> fieldTypeSelector = null) { ChoGuard.ArgumentNotNull(recordType, nameof(recordType)); if (!name.IsNullOrEmpty()) { if (subRecordType != null) { MapRecordFieldsForType(subRecordType); } string fnTrim = fieldName.IsNullOrWhiteSpace() ? name.NTrim() : fieldName; ChoJSONRecordFieldConfiguration fc = null; PropertyDescriptor pd = null; if (JSONRecordFieldConfigurations.Any(o => o.FieldName == fnTrim)) { fc = JSONRecordFieldConfigurations.Where(o => o.FieldName == fnTrim).First(); JSONRecordFieldConfigurations.Remove(fc); pd = ChoTypeDescriptor.GetNestedProperty(recordType, fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } else if (subRecordType != null) { pd = ChoTypeDescriptor.GetNestedProperty(subRecordType, fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } else { pd = ChoTypeDescriptor.GetNestedProperty(recordType, fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } var nfc = new ChoJSONRecordFieldConfiguration(fnTrim, pd != null ? ChoTypeDescriptor.GetPropetyAttribute <ChoJSONRecordFieldAttribute>(pd) : null, pd != null ? pd.Attributes.OfType <Attribute>().ToArray() : null) { }; nfc.JSONPath = !jsonPath.IsNullOrWhiteSpace() ? jsonPath : nfc.JSONPath; nfc.FieldType = fieldType != null ? fieldType : nfc.FieldType; nfc.FieldValueTrimOption = fieldValueTrimOption; nfc.FieldName = fieldName.IsNullOrWhiteSpace() ? (name.IsNullOrWhiteSpace() ? nfc.FieldName : name) : fieldName; nfc.ValueConverter = valueConverter != null ? valueConverter : nfc.ValueConverter; nfc.CustomSerializer = customSerializer != null ? customSerializer : nfc.CustomSerializer; nfc.DefaultValue = defaultValue != null ? defaultValue : nfc.DefaultValue; nfc.FallbackValue = fallbackValue != null ? fallbackValue : nfc.FallbackValue; nfc.FormatText = !formatText.IsNullOrWhiteSpace() ? formatText : nfc.FormatText; nfc.ItemConverter = itemConverter != null ? itemConverter : nfc.ItemConverter; nfc.IsArray = isArray != null ? isArray : nfc.IsArray; nfc.NullValue = !nullValue.IsNullOrWhiteSpace() ? nullValue : nfc.NullValue; nfc.FieldTypeSelector = fieldTypeSelector != null ? fieldTypeSelector : nfc.FieldTypeSelector; if (fullyQualifiedMemberName.IsNullOrWhiteSpace()) { nfc.PropertyDescriptor = fc != null ? fc.PropertyDescriptor : pd; nfc.DeclaringMember = fc != null ? fc.DeclaringMember : fullyQualifiedMemberName; } else { if (subRecordType == null) { pd = ChoTypeDescriptor.GetNestedProperty(recordType, fullyQualifiedMemberName); } else { pd = ChoTypeDescriptor.GetNestedProperty(subRecordType, fullyQualifiedMemberName); } nfc.PropertyDescriptor = pd; nfc.DeclaringMember = fullyQualifiedMemberName; } if (pd != null) { if (nfc.FieldType == null) { nfc.FieldType = pd.PropertyType; } } if (subRecordType == null) { JSONRecordFieldConfigurations.Add(nfc); } else { AddFieldForType(subRecordType, nfc); } } }
internal void WithField(string name, string jsonPath = null, Type fieldType = null, ChoFieldValueTrimOption fieldValueTrimOption = ChoFieldValueTrimOption.Trim, string fieldName = null, Func <object, object> valueConverter = null, Func <object, object> itemConverter = null, Func <object, object> customSerializer = null, object defaultValue = null, object fallbackValue = null, string fullyQualifiedMemberName = null, string formatText = null, bool isArray = true, string nullValue = null, Type recordType = null, Type subRecordType = null, Func <JObject, Type> fieldTypeSelector = null) { ChoGuard.ArgumentNotNull(recordType, nameof(recordType)); if (!name.IsNullOrEmpty()) { if (subRecordType != null) { MapRecordFieldsForType(subRecordType); } string fnTrim = name.NTrim(); ChoJSONRecordFieldConfiguration fc = null; PropertyDescriptor pd = null; if (JSONRecordFieldConfigurations.Any(o => o.Name == fnTrim)) { fc = JSONRecordFieldConfigurations.Where(o => o.Name == fnTrim).First(); JSONRecordFieldConfigurations.Remove(fc); } else if (subRecordType != null) { pd = ChoTypeDescriptor.GetNestedProperty(subRecordType, fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } else { pd = ChoTypeDescriptor.GetNestedProperty(recordType, fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } var nfc = new ChoJSONRecordFieldConfiguration(fnTrim, jsonPath) { FieldType = fieldType, FieldValueTrimOption = fieldValueTrimOption, FieldName = fieldName.IsNullOrWhiteSpace() ? name : fieldName, ValueConverter = valueConverter, CustomSerializer = customSerializer, DefaultValue = defaultValue, FallbackValue = fallbackValue, FormatText = formatText, ItemConverter = itemConverter, IsArray = isArray, NullValue = nullValue, FieldTypeSelector = fieldTypeSelector, }; if (fullyQualifiedMemberName.IsNullOrWhiteSpace()) { nfc.PropertyDescriptor = fc != null ? fc.PropertyDescriptor : pd; nfc.DeclaringMember = fc != null ? fc.DeclaringMember : fullyQualifiedMemberName; } else { if (subRecordType == null) { pd = ChoTypeDescriptor.GetNestedProperty(recordType, fullyQualifiedMemberName); } else { pd = ChoTypeDescriptor.GetNestedProperty(subRecordType, fullyQualifiedMemberName); } nfc.PropertyDescriptor = pd; nfc.DeclaringMember = fullyQualifiedMemberName; } if (pd != null) { if (nfc.FieldType == null) { nfc.FieldType = pd.PropertyType; } } if (subRecordType == null) { JSONRecordFieldConfigurations.Add(nfc); } else { AddFieldForType(subRecordType, nfc); } } }
private void DiscoverRecordFields(Type recordType, string declaringMember = null, bool optIn = false) { if (!IsDynamicObject) // recordType != typeof(ExpandoObject)) { Type pt = null; if (optIn) //ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType<ChoJSONRecordFieldAttribute>().Any()).Any()) { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { pt = pd.PropertyType.GetUnderlyingType(); if (!pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt)) { DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn); } else if (pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any()) { var obj = new ChoJSONRecordFieldConfiguration(pd.Name, pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().First(), pd.Attributes.OfType <Attribute>().ToArray()); obj.FieldType = pt; obj.PropertyDescriptor = pd; obj.DeclaringMember = declaringMember == null ? null : "{0}.{1}".FormatString(declaringMember, pd.Name); JSONRecordFieldConfigurations.Add(obj); } } } else { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { pt = pd.PropertyType.GetUnderlyingType(); if (!pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt)) { DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn); } else { var obj = new ChoJSONRecordFieldConfiguration(pd.Name, (string)null); obj.FieldType = pt; obj.PropertyDescriptor = pd; obj.DeclaringMember = declaringMember == null ? null : "{0}.{1}".FormatString(declaringMember, pd.Name); StringLengthAttribute slAttr = pd.Attributes.OfType <StringLengthAttribute>().FirstOrDefault(); if (slAttr != null && slAttr.MaximumLength > 0) { obj.Size = slAttr.MaximumLength; } DisplayAttribute dpAttr = pd.Attributes.OfType <DisplayAttribute>().FirstOrDefault(); if (dpAttr != null) { if (!dpAttr.ShortName.IsNullOrWhiteSpace()) { obj.FieldName = dpAttr.ShortName; } else if (!dpAttr.Name.IsNullOrWhiteSpace()) { obj.FieldName = dpAttr.Name; } } JSONRecordFieldConfigurations.Add(obj); } } } } }
public override void Validate(object state) { if (TurnOnAutoDiscoverJsonConverters) { ChoJSONConvertersCache.Init(); } if (_jsonSerializerSettings != null) { foreach (var conv in GetJSONConverters()) { _jsonSerializerSettings.Converters.Add(conv); } foreach (var conv in _jsonSerializerSettings.Converters.OfType <IChoJSONConverter>()) { conv.Serializer = JsonSerializer; conv.Context = new ChoDynamicObject(); conv.Context.Configuration = this; } foreach (var conv in _jsonSerializerSettings.Converters) { JsonSerializer.Converters.Add(conv); } } if (RecordType != null) { Init(RecordType); } base.Validate(state); string[] fieldNames = null; JObject jObject = null; if (state is Tuple <long, JObject> ) { jObject = ((Tuple <long, JObject>)state).Item2; } else { fieldNames = state as string[]; } if (fieldNames != null && JSONRecordFieldConfigurations.Count > 0 && FlattenNode) { JSONRecordFieldConfigurations.Clear(); } if (AutoDiscoverColumns && JSONRecordFieldConfigurations.Count == 0) { if (RecordType != null && !IsDynamicObject && /*&& RecordType != typeof(ExpandoObject)*/ ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any()).Any()) { MapRecordFields(RecordType); } else if (jObject != null) { Dictionary <string, ChoJSONRecordFieldConfiguration> dict = new Dictionary <string, ChoJSONRecordFieldConfiguration>(StringComparer.CurrentCultureIgnoreCase); string name = null; foreach (var attr in jObject.Properties()) { name = attr.Name; if (!dict.ContainsKey(name)) { dict.Add(name, new ChoJSONRecordFieldConfiguration(name, (string)null)); } else { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); } } foreach (ChoJSONRecordFieldConfiguration obj in dict.Values) { JSONRecordFieldConfigurations.Add(obj); } } else if (!fieldNames.IsNullOrEmpty()) { foreach (string fn in fieldNames) { if (IgnoredFields.Contains(fn)) { continue; } var obj = new ChoJSONRecordFieldConfiguration(fn, (string)null); JSONRecordFieldConfigurations.Add(obj); } } } else { foreach (var fc in JSONRecordFieldConfigurations) { fc.ComplexJPathUsed = !(fc.JSONPath.IsNullOrWhiteSpace() || String.Compare(fc.FieldName, fc.JSONPath, true) == 0); } } //if (JSONRecordFieldConfigurations.Count <= 0) // throw new ChoRecordConfigurationException("No record fields specified."); //Validate each record field foreach (var fieldConfig in JSONRecordFieldConfigurations) { fieldConfig.Validate(this); } //Check field position for duplicate string[] dupFields = JSONRecordFieldConfigurations.GroupBy(i => i.FieldName) .Where(g => g.Count() > 1) .Select(g => g.Key).ToArray(); if (dupFields.Length > 0) { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(String.Join(",", dupFields))); } PIDict = new Dictionary <string, System.Reflection.PropertyInfo>(StringComparer.InvariantCultureIgnoreCase); PDDict = new Dictionary <string, PropertyDescriptor>(StringComparer.InvariantCultureIgnoreCase); foreach (var fc in JSONRecordFieldConfigurations) { var pd1 = fc.DeclaringMember.IsNullOrWhiteSpace() ? ChoTypeDescriptor.GetProperty(RecordType, fc.Name) : ChoTypeDescriptor.GetProperty(RecordType, fc.DeclaringMember); if (pd1 != null) { fc.PropertyDescriptor = pd1; } if (fc.PropertyDescriptor == null) { fc.PropertyDescriptor = TypeDescriptor.GetProperties(RecordType).AsTypedEnumerable <PropertyDescriptor>().Where(pd => pd.Name == fc.Name).FirstOrDefault(); } if (fc.PropertyDescriptor == null) { continue; } PIDict.Add(fc.Name, fc.PropertyDescriptor.ComponentType.GetProperty(fc.PropertyDescriptor.Name)); PDDict.Add(fc.Name, fc.PropertyDescriptor); } RecordFieldConfigurationsDict = JSONRecordFieldConfigurations.Where(i => !i.Name.IsNullOrWhiteSpace()).ToDictionary(i => i.Name); LoadNCacheMembers(JSONRecordFieldConfigurations); }
private void DiscoverRecordFields(Type recordType, string declaringMember, bool optIn = false) { if (!recordType.IsDynamicType()) { Type pt = null; if (ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType<ChoJSONRecordFieldAttribute>().Any()).Any()) { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { pt = pd.PropertyType.GetUnderlyingType(); bool optIn1 = ChoTypeDescriptor.GetProperties(pt).Where(pd1 => pd1.Attributes.OfType<ChoJSONRecordFieldAttribute>().Any()).Any(); if (optIn1 && !pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt) && FlatToNestedObjectSupport) { DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn1); } else if (pd.Attributes.OfType<ChoJSONRecordFieldAttribute>().Any()) { var obj = new ChoJSONRecordFieldConfiguration(pd.Name, pd.Attributes.OfType<ChoJSONRecordFieldAttribute>().First(), pd.Attributes.OfType<Attribute>().ToArray()); obj.FieldType = pt; obj.PropertyDescriptor = pd; obj.DeclaringMember = declaringMember == null ? null : "{0}.{1}".FormatString(declaringMember, pd.Name); if (!JSONRecordFieldConfigurations.Any(c => c.Name == pd.Name)) JSONRecordFieldConfigurations.Add(obj); } } } else { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { JsonIgnoreAttribute jiAttr = pd.Attributes.OfType<JsonIgnoreAttribute>().FirstOrDefault(); if (jiAttr != null) continue; pt = pd.PropertyType.GetUnderlyingType(); if (pt != typeof(object) && !pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt) && FlatToNestedObjectSupport) { DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn); } else { var obj = new ChoJSONRecordFieldConfiguration(pd.Name, (string)null); obj.FieldType = pt; obj.PropertyDescriptor = pd; obj.DeclaringMember = declaringMember == null ? null : "{0}.{1}".FormatString(declaringMember, pd.Name); StringLengthAttribute slAttr = pd.Attributes.OfType<StringLengthAttribute>().FirstOrDefault(); if (slAttr != null && slAttr.MaximumLength > 0) obj.Size = slAttr.MaximumLength; ChoUseJSONSerializationAttribute sAttr = pd.Attributes.OfType<ChoUseJSONSerializationAttribute>().FirstOrDefault(); if (sAttr != null) obj.UseJSONSerialization = true; JsonPropertyAttribute jAttr = pd.Attributes.OfType<JsonPropertyAttribute>().FirstOrDefault(); if (jAttr != null && !jAttr.PropertyName.IsNullOrWhiteSpace()) { obj.FieldName = jAttr.PropertyName; } else { DisplayAttribute dpAttr = pd.Attributes.OfType<DisplayAttribute>().FirstOrDefault(); if (dpAttr != null) { if (!dpAttr.ShortName.IsNullOrWhiteSpace()) obj.FieldName = dpAttr.ShortName; else if (!dpAttr.Name.IsNullOrWhiteSpace()) obj.FieldName = dpAttr.Name; } } DisplayFormatAttribute dfAttr = pd.Attributes.OfType<DisplayFormatAttribute>().FirstOrDefault(); if (dfAttr != null && !dfAttr.DataFormatString.IsNullOrWhiteSpace()) { obj.FormatText = dfAttr.DataFormatString; } if (dfAttr != null && !dfAttr.NullDisplayText.IsNullOrWhiteSpace()) { obj.NullValue = dfAttr.NullDisplayText; } if (!JSONRecordFieldConfigurations.Any(c => c.Name == pd.Name)) JSONRecordFieldConfigurations.Add(obj); } } } } }
public override void Validate(object state) { if (RecordType != null) { Init(RecordType); } base.Validate(state); string[] fieldNames = null; JObject jObject = null; if (state is Tuple<long, JObject>) jObject = ((Tuple<long, JObject>)state).Item2; else fieldNames = state as string[]; if (AutoDiscoverColumns && JSONRecordFieldConfigurations.Count == 0) { if (RecordType != null && !IsDynamicObject /*&& RecordType != typeof(ExpandoObject)*/ && ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Attributes.OfType<ChoJSONRecordFieldAttribute>().Any()).Any()) { MapRecordFields(RecordType); } else if (jObject != null) { Dictionary<string, ChoJSONRecordFieldConfiguration> dict = new Dictionary<string, ChoJSONRecordFieldConfiguration>(StringComparer.CurrentCultureIgnoreCase); string name = null; foreach (var attr in jObject.Properties()) { name = attr.Name; if (!dict.ContainsKey(name)) dict.Add(name, new ChoJSONRecordFieldConfiguration(name, (string)null)); else { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); } } foreach (ChoJSONRecordFieldConfiguration obj in dict.Values) JSONRecordFieldConfigurations.Add(obj); } else if (!fieldNames.IsNullOrEmpty()) { foreach (string fn in fieldNames) { var obj = new ChoJSONRecordFieldConfiguration(fn, (string)null); JSONRecordFieldConfigurations.Add(obj); } } } else { foreach (var fc in JSONRecordFieldConfigurations) { fc.ComplexJPathUsed = !(fc.JSONPath.IsNullOrWhiteSpace() || String.Compare(fc.FieldName, fc.JSONPath, true) == 0); } } if (JSONRecordFieldConfigurations.Count <= 0) throw new ChoRecordConfigurationException("No record fields specified."); //Validate each record field foreach (var fieldConfig in JSONRecordFieldConfigurations) fieldConfig.Validate(this); //Check field position for duplicate string[] dupFields = JSONRecordFieldConfigurations.GroupBy(i => i.Name) .Where(g => g.Count() > 1) .Select(g => g.Key).ToArray(); if (dupFields.Length > 0) throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(String.Join(",", dupFields))); PIDict = new Dictionary<string, System.Reflection.PropertyInfo>(); PDDict = new Dictionary<string, PropertyDescriptor>(); foreach (var fc in JSONRecordFieldConfigurations) { if (fc.PropertyDescriptor == null) fc.PropertyDescriptor = ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Name == fc.Name).FirstOrDefault(); if (fc.PropertyDescriptor == null) continue; PIDict.Add(fc.PropertyDescriptor.Name, fc.PropertyDescriptor.ComponentType.GetProperty(fc.PropertyDescriptor.Name)); PDDict.Add(fc.PropertyDescriptor.Name, fc.PropertyDescriptor); } RecordFieldConfigurationsDict = JSONRecordFieldConfigurations.Where(i => !i.Name.IsNullOrWhiteSpace()).ToDictionary(i => i.Name); LoadNCacheMembers(JSONRecordFieldConfigurations); }
private Type DiscoverRecordFields(Type recordType, string declaringMember, bool optIn = false, List <ChoJSONRecordFieldConfiguration> recordFieldConfigurations = null, bool isTop = false) { if (recordType == null) { return(recordType); } if (!recordType.IsDynamicType()) { Type pt = null; if (ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any()).Any()) { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { pt = pd.PropertyType.GetUnderlyingType(); bool optIn1 = ChoTypeDescriptor.GetProperties(pt).Where(pd1 => pd1.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any()).Any(); if (optIn1 && !pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt) && FlatToNestedObjectSupport) { DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn1, recordFieldConfigurations, false); } else if (pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().Any()) { var obj = new ChoJSONRecordFieldConfiguration(pd.Name, pd.Attributes.OfType <ChoJSONRecordFieldAttribute>().First(), pd.Attributes.OfType <Attribute>().ToArray()); obj.FieldType = pt; obj.PropertyDescriptor = pd; obj.DeclaringMember = declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name); if (recordFieldConfigurations != null) { if (!recordFieldConfigurations.Any(c => c.Name == pd.Name)) { recordFieldConfigurations.Add(obj); } } } } } else { if (isTop) { if (typeof(IList).IsAssignableFrom(recordType) || (recordType.IsGenericType && recordType.GetGenericTypeDefinition() == typeof(IList <>))) { throw new ChoParserException("Record type not supported."); } else if (typeof(IDictionary <string, object>).IsAssignableFrom(recordType)) { recordType = typeof(ExpandoObject); return(recordType); } else if (typeof(IDictionary).IsAssignableFrom(recordType)) { recordType = typeof(ExpandoObject); return(recordType); } } if (recordType.IsSimple()) { var obj = new ChoJSONRecordFieldConfiguration("Value", "$.Value"); obj.FieldType = recordType; recordFieldConfigurations.Add(obj); return(recordType); } foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { JsonIgnoreAttribute jiAttr = pd.Attributes.OfType <JsonIgnoreAttribute>().FirstOrDefault(); if (jiAttr != null) { continue; } pt = pd.PropertyType.GetUnderlyingType(); if (pt != typeof(object) && !pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt) && FlatToNestedObjectSupport) { DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn, recordFieldConfigurations, false); } else { var obj = new ChoJSONRecordFieldConfiguration(pd.Name, ChoTypeDescriptor.GetPropetyAttribute <ChoJSONRecordFieldAttribute>(pd), pd.Attributes.OfType <Attribute>().ToArray()); obj.FieldType = pt; obj.PropertyDescriptor = pd; obj.DeclaringMember = declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name); StringLengthAttribute slAttr = pd.Attributes.OfType <StringLengthAttribute>().FirstOrDefault(); if (slAttr != null && slAttr.MaximumLength > 0) { obj.Size = slAttr.MaximumLength; } ChoUseJSONSerializationAttribute sAttr = pd.Attributes.OfType <ChoUseJSONSerializationAttribute>().FirstOrDefault(); if (sAttr != null) { obj.UseJSONSerialization = sAttr.Flag; } ChoJSONPathAttribute jpAttr = pd.Attributes.OfType <ChoJSONPathAttribute>().FirstOrDefault(); if (jpAttr != null) { obj.JSONPath = jpAttr.JSONPath; } JsonPropertyAttribute jAttr = pd.Attributes.OfType <JsonPropertyAttribute>().FirstOrDefault(); if (jAttr != null && !jAttr.PropertyName.IsNullOrWhiteSpace()) { obj.FieldName = jAttr.PropertyName; obj.JSONPath = jAttr.PropertyName; obj.Order = jAttr.Order; } else { DisplayNameAttribute dnAttr = pd.Attributes.OfType <DisplayNameAttribute>().FirstOrDefault(); if (dnAttr != null && !dnAttr.DisplayName.IsNullOrWhiteSpace()) { obj.FieldName = dnAttr.DisplayName.Trim(); } else { DisplayAttribute dpAttr = pd.Attributes.OfType <DisplayAttribute>().FirstOrDefault(); if (dpAttr != null) { if (!dpAttr.ShortName.IsNullOrWhiteSpace()) { obj.FieldName = dpAttr.ShortName; } else if (!dpAttr.Name.IsNullOrWhiteSpace()) { obj.FieldName = dpAttr.Name; } obj.Order = dpAttr.Order; } else { ColumnAttribute clAttr = pd.Attributes.OfType <ColumnAttribute>().FirstOrDefault(); if (clAttr != null) { obj.Order = clAttr.Order; if (!clAttr.Name.IsNullOrWhiteSpace()) { obj.FieldName = clAttr.Name; } } } } } DisplayFormatAttribute dfAttr = pd.Attributes.OfType <DisplayFormatAttribute>().FirstOrDefault(); if (dfAttr != null && !dfAttr.DataFormatString.IsNullOrWhiteSpace()) { obj.FormatText = dfAttr.DataFormatString; } if (dfAttr != null && !dfAttr.NullDisplayText.IsNullOrWhiteSpace()) { obj.NullValue = dfAttr.NullDisplayText; } if (recordFieldConfigurations != null) { if (!recordFieldConfigurations.Any(c => c.Name == pd.Name)) { recordFieldConfigurations.Add(obj); } } } } } } return(recordType); }
private ChoJSONReader <T> WithField(string name, string jsonPath = null, Type fieldType = null, ChoFieldValueTrimOption fieldValueTrimOption = ChoFieldValueTrimOption.Trim, bool isJSONAttribute = false, string fieldName = null, Func <object, object> valueConverter = null, Func <object, object> itemConverter = null, Func <object, object> customSerializer = null, object defaultValue = null, object fallbackValue = null, string fullyQualifiedMemberName = null, string formatText = null, bool isArray = true, string nullValue = null, Type recordType = null, Func <JObject, Type> fieldTypeSelector = null) { if (!name.IsNullOrEmpty()) { if (!_clearFields) { ClearFields(); Configuration.MapRecordFields(Configuration.RecordType); } if (recordType != null) { Configuration.MapRecordFieldsForType(recordType); } string fnTrim = name.NTrim(); ChoJSONRecordFieldConfiguration fc = null; PropertyDescriptor pd = null; if (Configuration.JSONRecordFieldConfigurations.Any(o => o.Name == fnTrim)) { fc = Configuration.JSONRecordFieldConfigurations.Where(o => o.Name == fnTrim).First(); Configuration.JSONRecordFieldConfigurations.Remove(fc); } else if (recordType != null) { pd = ChoTypeDescriptor.GetNestedProperty(recordType, fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } else { pd = ChoTypeDescriptor.GetNestedProperty(typeof(T), fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } var nfc = new ChoJSONRecordFieldConfiguration(fnTrim, jsonPath) { FieldType = fieldType, FieldValueTrimOption = fieldValueTrimOption, FieldName = fieldName, ValueConverter = valueConverter, CustomSerializer = customSerializer, DefaultValue = defaultValue, FallbackValue = fallbackValue, FormatText = formatText, ItemConverter = itemConverter, IsArray = isArray, NullValue = nullValue, FieldTypeSelector = fieldTypeSelector, }; if (fullyQualifiedMemberName.IsNullOrWhiteSpace()) { nfc.PropertyDescriptor = fc != null ? fc.PropertyDescriptor : pd; nfc.DeclaringMember = fc != null ? fc.DeclaringMember : fullyQualifiedMemberName; } else { if (recordType == null) { pd = ChoTypeDescriptor.GetNestedProperty(typeof(T), fullyQualifiedMemberName); } else { pd = ChoTypeDescriptor.GetNestedProperty(recordType, fullyQualifiedMemberName); } nfc.PropertyDescriptor = pd; nfc.DeclaringMember = fullyQualifiedMemberName; } if (pd != null) { if (nfc.FieldType == null) { nfc.FieldType = pd.PropertyType; } } if (recordType == null) { Configuration.JSONRecordFieldConfigurations.Add(nfc); } else { Configuration.Add(recordType, nfc); } } return(this); }
public ChoContractResolverJsonConverter(ChoJSONRecordFieldConfiguration fc, CultureInfo culture, Type objType) { _fc = fc; _culture = culture; _objType = objType; }