Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create maps from dynamic collection no longer works: Unable to cast object of type System.String to System.Object) #1500

Closed
ruslanss opened this issue Apr 14, 2020 · 4 comments
Labels

Comments

@ruslanss
Copy link
Contributor

Hi, we are porting legacy code to dotnet standard and are facing an issue which wasn't present in CsvHelper 2.5.0 net451.

The issue appears to be that CsvReader can't manage to resolve the correct ReturnType of the underlying properties in the mappings and is trying to map them all to System.Object

I have managed to reproduce it with a unit test in your solution:


[TestMethod]
public void CanCreateMapsFromDynamicList()
{
	var data = new List<string[]>
	{
		new[] { "Col1", "Col2" },
		new[] { "1", "one" },
		new[] { "2", "two" }
	};

	var queue = new Queue<string[]>(data);
	var parserMock = new ParserMock(queue);

	var csvReader = new CsvReader(parserMock);
	csvReader.Configuration.RegisterClassMap<SomeTypeClassMap>();

	var records = csvReader.GetRecords<SomeType>().ToList();

	Assert.IsNotNull(records);
	Assert.AreEqual(2, records.Count);

}

public class SomeTypeClassMap : ClassMap<SomeType>
{
	public SomeTypeClassMap()
	{
		Map(x => x.Id).Ignore();
		var t = new SomeType();

		foreach (var mapping in t.Mappings)
		{
			Map(mapping);
		}
	}
}

public class SomeType
{
	public int Id { get; set; }
	public string Col1 { get; set; }
	public string Col2 { get; set; }

	public IEnumerable<Expression<Func<SomeType, dynamic>>> Mappings =>
		new List<Expression<Func<SomeType, dynamic>>> {i => i.Col1, i => i.Col2};
}

Error reported:

Test method CsvHelper.Tests.CsvReaderMappingTestsRuslan.CanCreateMapsFromDynamicList threw exception:
System.InvalidCastException: Unable to cast object of type 'CsvHelper.Configuration.MemberMap2[CsvHelper.Tests.CsvReaderMappingTestsRuslan+SomeType,System.String]' to type 'CsvHelper.Configuration.MemberMap2[CsvHelper.Tests.CsvReaderMappingTestsRuslan+SomeType,System.Object]'.

@ruslanss ruslanss added the bug label Apr 14, 2020
@JoshClose
Copy link
Owner

Looks like the signature on Map has changed. It now requires the actual member type as a generic instead of object.

Maybe there is another way around this. What is your goal of doing this?

@ruslanss
Copy link
Contributor Author

Our use case is this: we import a bunch of different CSV documents, all of which have a set of common properties (columns) contained in a base-class and some individual defined in each respective entity class. This design allowed us to use a single ClassMap function for all of them before the upgrade. Do you think there might be a simple work-around?

@ruslanss
Copy link
Contributor Author

Looks like the signature on Map has changed. It now requires the actual member type as a generic instead of object.

Maybe there is another way around this. What is your goal of doing this?

thanks for the hint! i have fixed this and raised a pull request: #1505

@JoshClose
Copy link
Owner

Pull request merged. This will be in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants
@JoshClose @ruslanss and others