private static void ProcessTypedErrors <T>(CustomClassMap <T> classMap, ParsedItemResponse <T> parsedItem,
                                                   Expression <Func <T, ICollection <KeyValuePair <string, string> > > > typedValidator = null)
        {
            if (typedValidator == null || parsedItem.Data == null)
            {
                return;
            }


            //Run typed validator.  Should return a list of key value pairs. Key bing the typed property name, value being the error
            parsedItem.TypedErrors = typedValidator.Compile()(parsedItem.Data);
            if (!parsedItem.TypedErrors.IsNullOrEmpty())
            {
                //Now we want to add the errors to the parsed item with the key being the classmap header definition.
                //The custom class map should have the typed property name so we can map it
                var csvHeaderInfo = classMap.GetHeaderDefinitions();
                foreach (var typedError in parsedItem.TypedErrors.ToList())
                {
                    var headerKey = csvHeaderInfo
                                    .Where(e => e.Value.TypedPropertyName == typedError.Key)
                                    .Select(e => e.Key)
                                    .FirstOrDefault();

                    if (!headerKey.IsEmpty())
                    {
                        parsedItem.Errors.Add(new ParsedItemError(headerKey, typedError.Value));
                    }

                    parsedItem.TypedErrors.Remove(typedError);
                }
            }
        }
Exemplo n.º 2
0
        private ParsedEnumerableResponse <T> MapDataAndParse <T>(CustomClassMap <T> classMap, IEnumerable <string> headerRow, IEnumerable <IEnumerable <string> > rowData)
        {
            var csv = string.Join(",", headerRow);

            foreach (var row in rowData)
            {
                csv += Environment.NewLine;
                csv += string.Join(",", row);
            }
            return(_csvUtility.ParseCsvFile(new MemoryStream(Encoding.ASCII.GetBytes(csv)), classMap));
        }
Exemplo n.º 3
0
        public ParsedEnumerableResponse <T> ParseCsvFile <T>(Stream fileStream, CustomClassMap <T> classMap,
                                                             Expression <Func <T> > initialValueFunc = null, Expression <Func <T, ICollection <KeyValuePair <string, string> > > > typedValidator = null)
        {
            var response = new ParsedEnumerableResponse <T>();

            using (fileStream)
                using (var reader = new StreamReader(fileStream))
                    using (var parser = InitCsvReader(reader, classMap))
                    {
                        response.FoundHeaders = parser.Context.Reader.HeaderRecord;
                        while (parser.Read())
                        {
                            response.Items.Add(parser.SafeParseRecord(classMap, initialValueFunc, typedValidator));
                        }
                    }

            return(response);
        }
        public static ParsedItemResponse <T> SafeParseRecord <T>(this CsvReader parser, CustomClassMap <T> classMap,
                                                                 Expression <Func <T> > initialValueFunc = null, Expression <Func <T, ICollection <KeyValuePair <string, string> > > > typedValidator = null)
        {
            var parsedItem = new ParsedItemResponse <T>(parser.Context.Reader.Parser.Row - 1, parser.Parser.Record);

            var valueType = typeof(T);

            var value = initialValueFunc == null ? (T)Activator.CreateInstance(valueType) : initialValueFunc.Compile()();

            foreach (var memberMap in classMap.MemberMaps)
            {
                var data              = memberMap.Data;
                var valueProperty     = valueType.GetProperty(data.Member.Name);
                var vaulePropertyType = data.Member.MemberType();
                var csvHeaderName     = data.Names.First();

                try
                {
                    var propertyValue = parser.GetField(vaulePropertyType, csvHeaderName, data.TypeConverter);

                    //If we have an error dont waste memory using reflection as the item is incomplete
                    if (!parsedItem.HasErrors)
                    {
                        valueProperty.SetValue(value, propertyValue);
                    }
                }
                catch (Exception ex)
                {
                    if (!data.IsOptional)
                    {
                        if (ex is TypeConverterException || ex is FormatException)
                        {
                            parsedItem.Errors.Add(new ParsedItemError(csvHeaderName, $"Failed to convert {csvHeaderName} to {valueProperty.Name}"));
                        }
                        else if (ex is CsvHelperException csvHelperException)
                        {
                            parsedItem.Errors.Add(new ParsedItemError(csvHeaderName, csvHelperException.GetFriendlyErrorMessage()));
                        }
                        else
                        {
                            parsedItem.Errors.Add(new ParsedItemError(csvHeaderName, "Unhandled exception parsing record"));
                        }
                    }
                }
            }

            if (!parsedItem.HasErrors)
            {
                parsedItem.Data = value;
                ProcessTypedErrors(classMap, parsedItem, typedValidator);
            }

            return(parsedItem);
        }