Exemple #1
0
        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);
            }
        }
Exemple #3
0
        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;
 }
Exemple #5
0
        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);
        }
Exemple #8
0
        //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);
        }
Exemple #9
0
        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);
            }
        }
Exemple #10
0
        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);
            }
        }
Exemple #12
0
        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);
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        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);
        }
Exemple #17
0
 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);
                }
            }
        }
Exemple #19
0
        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);
                }
            }
        }
Exemple #20
0
 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);
        }
Exemple #25
0
        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;
 }