/// <summary> /// verifies parser fields - class properties /// </summary> /// <param name="parser">parser</param> public void VerifyHeaders(IFieldBasedParser <TRecord> parser) { Arguments.NotNull(parser, nameof(parser)); // Verify Class: // For each property of TModel check if class properties has corresponding csv fields // save header -> propertyInfo in dictionary var classProperties = typeof(TRecord).GetProperties(); var fileHeaders = parser.FieldHeaders().Select(m => m.Trim('|').ToUpperInvariant()); var extraProperties = new List <string>(); foreach (var property in classProperties) { var normalizedName = property.Name.ToUpperInvariant(); var aliases = ReflectionHelper.Attributes <MappingAliasAttribute>(property); if (fileHeaders.Contains(normalizedName)) { this.headerToProperty.Add(normalizedName, property); } else if (aliases != null) { foreach (MappingAliasAttribute alias in aliases) { var normalizedAlias = alias.AlternateName.ToUpperInvariant(); if (fileHeaders.Contains(normalizedAlias)) { this.headerToProperty.Add(normalizedAlias, property); break; } } } else { extraProperties.Add(property.Name); } } // Verify Header: // For each header, check if parser fields have matching class properties: // check if header in dictionary var extraFileHeaders = new List <string>(); foreach (var header in fileHeaders) { if (!this.headerToProperty.ContainsKey(header)) { extraFileHeaders.Add(header); } } if (extraFileHeaders.Count + extraProperties.Count > 0) { var message = string.Format( CultureInfo.InvariantCulture, "headers absent in properties: {0}\n properties absent in headers: {1}", string.Join(", ", extraFileHeaders.ToArray()), string.Join(", ", extraProperties.ToArray())); var stopFlag = (!this.allowFileToHaveExtraProperties && extraFileHeaders.Any()) || (!this.allowClassToHaveExtraProperties && extraProperties.Any()); if (stopFlag) { throw new InvalidOperationException(message); } } }