-
Source/destination typesSource (Short Version) public class PaymentIntent : StripeEntity<PaymentIntent>, IHasId, IHasMetadata, IHasObject
{
[JsonProperty("id")]
public string Id { get; set; }
} Destination (Short Version) [Table("PaymentIntentLog")]
public class PaymentIntentLog : IEntity
{
public int ID { get; set; } = 0;
public string PaymentIntentID { get; set; } = null;
} Mapping configurationcfg.CreateMap<PaymentIntent, PaymentIntentLog>(MemberList.None)
.ForMember(dest => dest.PaymentIntentID,
opt => opt.MapFrom(src => src.Id)
); Version: 11.0.1Coming from 10.1.1. Expected behaviorUpgrading from 10 to 11 and replacing '.ForAllOtherMembers(opt => opt.Ignore())' with 'MemberList.None', I expected everything to work as it always has. Actual behaviorInstead, the above configuration throws an exception, saying that the "input string was not in a correct format" for destination property 'ID'. The string property 'Id' from the source object must be mapped to the string property 'PaymentIntentID' property on the destination object. Why is it even attempting to do anything for destination property 'ID', when it shouldn't, due to MemberList.None? I am forced to explicitly tell it to not do anything with the destination object's 'ID' property, in order to get it back to working again: .ForMember(dest => dest.ID,
opt => opt.Ignore()
); Looks like it's trying to match the destination's uppercase 'ID' int property to the source's camelcase 'Id' string property, even though the latter is already explicitly being mapped to the destination's 'PaymentIntentID' string property. Parsing an int fails, because Stripe's Payment Intent 'Id' string property gets a value of the form:
Could it be that AutoMapper 10 was case sensitive and AutoMapper 11 isn't? This unexpected behavior makes me feel like it could unexpectedly go wrong with other mappings, as well. Feels a bit risky updating to version 11. Exception
Steps to reproducePaymentIntentLog paymentIntentLog = this.mapper.Map(paymentIntent, paymentIntentLog); |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 3 replies
-
I'm not sure I'd use AutoMapper for this case, I have yet to see a case for the above where manual code wasn't more obvious. If you have to ignore every mapping except for what is explicitly mapped, you don't have AutoMapper you have ManualMapper. That method was removed because it was so confusing about what the expected behavior should be. I regret ever adding it in the first place. |
Beta Was this translation helpful? Give feedback.
-
The documentation itself suggests MemberList.None instead of ForAllOtherMembers. So that's the best I got. In my view, this is exactly the kind of stuff you'd use AutoMapper for. Keep in mind, these entities are shortened versions, that I edited for brevity. There are many other properties in these entities. I only want to map a select set of my choosing, explicitly, to whichever properties I want. I dislike the idea of having to explicitly list every member I want to ignore. At some point, you'll add more properties to your entities, and you forget to add them to your AutoMapping's growing list. Now you've got exceptions from AutoMappings that used to work. I think we have a real use case here for ForAllOtherMembers. Can we have it back, please? |
Beta Was this translation helpful? Give feedback.
-
What's wrong with Manual/Explicit Mapper functionality in a lib called AutoMapper? If AutoMapper was never intended for that purpose, then why did it include ForAllOtherMembers() up to version 11? Why would it matter if your example 1 is more verbose than example 2, when example 1 is stuffed into an AutoMappings file? You're supposed to be able to map one object to another with this. It says so right on the frontpage:
For me, it just put some fuss back in. But thanks for the ConvertUsing() suggestion. Guess I'll refactor to that. Added benefit: I move towards less verbosity. |
Beta Was this translation helpful? Give feedback.
-
What's AutoMapper intended for, actually? Mapping an object to another object with equal properties? So why not just call it Cloner, then? Why even allow for mappings between 2 different objects? |
Beta Was this translation helpful? Give feedback.
.ForAllOtherMembers(opt => opt.Ignore())
is not equivalent toMemberList.None
exactly. It does not cover the case where members actually map.I'm not sure I'd use AutoMapper for this case, I have yet to see a case for the above where manual code wasn't more obvious. If you have to ignore every mapping except for what is explicitly mapped, you don't have AutoMapper you have ManualMapper. That method was removed because it was so confusing about what the expected behavior should be. I regret ever adding it in the first place.