I'm new to AutoMapper, I want to post this issue on their github, but considering their issue template:
If you're new to AutoMapper, please ask a question on StackOverflow first and come back here if the people there consider it a bug.
I have to post here.
To simplify the problem, I removed unnecessary code as much as possible.
class Rule {
public ReadOnlyCollection<string>? Collection { get; set; }
}
var config = new MapperConfiguration(c => {
c.CreateMap<Rule, Rule>();
});
config.AssertConfigurationIsValid();
var mapper = config.CreateMapper();
var source = new Rule {
Collection = Array.AsReadOnly(new [] { "a", "b", "c" })
};
var destination = new Rule();
// The following line throw an exception:
// ArgumentException: System.Collections.ObjectModel.ReadOnlyCollection`1[System.String]
// needs to have a constructor with 0 args or only optional args.
// Validate your configuration for details.
mapper.Map(source, destination);
And docs said:
When calling Map with an existing readonly collection, such as IEnumerable<>, the setter will be used to replace it. If you actually have to map into that collection, you need to change its type to a writable collection, such as List<>, HashSet<>, ICollection<>, IList<> or IList. Alternatively, you can remove the setter or set UseDestinationValue.
But the exception seems tell me mapper is going to do a deep clone rather than the setter will be used to replace it
.
AutoMapper version: 11.0.1
I'm sorry for my recklessness.
In fact, the Rule
class has more than one ReadOnlyCollection<string>?
property:
class Rule {
public ReadOnlyCollection<string>? CollectionA { get; set; }
public ReadOnlyCollection<string>? CollectionB { get; set; }
}
So, the following code as my origin question never initialize the CollectionB
:
var source = new Rule {
CollectionA = Array.AsReadOnly(new [] { "a", "b", "c" })
};
var destination = new Rule();
mapper.Map(source, destination);
It cause the null
issue of AutoMapper, the solution is append ForAllMembers(o => o.AllowNull())
when CreateMap
var config = new MapperConfiguration(c => {
c.CreateMap<Rule, Rule>().ForAllMembers(o => o.AllowNull());
});
SORRY, EVERYONE!!!