Why this mapping in the example is not map correctly. When I change the suffix CAST to something else (CAST1) it maps correctly. How should I set the mapper to map correctly with the suffix CAST?
public class Class1
{
public string OBEC { get; set; }
public string OBEC_CAST { get; set; }
}
public class Class2
{
public string Obec { get; set; }
public string ObecCast { get; set; }
}
public void Map()
{
Class1 c1 = new Class1() { OBEC = "obec", OBEC_CAST = "cast obce" };
Class2 c2 = Mapper.Map<Class2>(c1);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
Mapper.Initialize(cfg =>
{
cfg.RecognizePrefixes(new string [0]);
cfg.RecognizePostfixes(new string[0]);
cfg.ClearPrefixes();
cfg.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
cfg.DestinationMemberNamingConvention = new PascalCaseNamingConvention();
cfg.CreateMap<Class1, Class2>();
});
}
Related
I was trying to implement a code to ignore a property (therefore mantaining the source value). I used the ignore method, which works most of the time. For some reason I noticed that sometimes the ignore sets the property value to null.
Do you know what could be problem?
I created the following code to reproduce the issue. I was expecting client.ContactDetails.First().Address to have the value "Old".
using AutoMapper;
class Program
{
static void Main(string[] args)
{
ClientMapperProfile clientMapperProfile = new ClientMapperProfile();
var configurationProvider = new MapperConfiguration(c => c.AddProfile(clientMapperProfile));
Mapper mapper = new Mapper(configurationProvider);
var client = new Client()
{
ContactDetails = new []
{
new ContactDetails()
{
Address= "Old"
}
}
};
var clientDto = new ClientDto()
{
ContactDetails = new []
{
new ContactDetailsDto()
{
Address = "New"
}
}
};
mapper.Map(clientDto,client);
Console.WriteLine(client.ContactDetails.First().Address);
}
}
public class Client
{
public ContactDetails[] ContactDetails { get; set; }
}
public class ContactDetails
{
public string Address { get; set; }
}
public class ClientDto
{
public ContactDetailsDto[] ContactDetails { get; set; }
}
public class ContactDetailsDto
{
public string Address { get; set; }
}
public class ClientMapperProfile : Profile
{
public ClientMapperProfile()
{
CreateMap<ClientDto, Client>();
CreateMap<ContactDetailsDto, ContactDetails>()
.ForMember(c => c.Address, opt => opt.Ignore());
}
}
I have 3 classes as you can see :
public class car
{
public int Id { set; get; }
public string Name { set; get; }
public List<CarTest> CarTest { get; set; }
public car(string name, int id, List<CarTest> carTests)
{
Id = id;
Name = name;
CarTest = carTests;
}
public car()
{
}
}
public class CarTest
{
public OVTest OV { get; set; }
public string CarOV { get; set; }
}
public class OVTest
{
public string Name { get; set; }
}
I want to edit my value as you can see :
static void Main(string[] args)
{
myctx myc = new myctx();
var cartests = new List<CarTest>();
var cartest = new CarTest();
var OV = new OVTest();
OV.Name = "editedName";
cartest.OV = OV;
cartest.CarOV = "2OV";
cartests.Add(cartest);
var editcar = new car("ee5155fe",2, cartests);
myc.ChangeTracker.TrackGraph(editcar, e =>e.Entry.State = EntityState.Modified);
myc.SaveChanges();
Console.ReadLine();
}
But I get this error :
System.InvalidOperationException: 'The property 'CarTestId' on entity type 'OVTest' is part of a key and so cannot be modified or marked as modified. To change the principal of an existing entity with an identifying foreign key first delete the dependent and invoke 'SaveChanges' then associate the dependent with the new principal.'
This is my config:
public class CarConfig : IEntityTypeConfiguration<car>
{
public void Configure(EntityTypeBuilder<car> builder)
{
builder.OwnsMany(u => u.CarTest);
builder.OwnsMany(u => u.CarTest).OwnsOne(c=>c.OV);
}
}
Hey I'm trying to map my generic class to concrete class but using it's interface.
My service returns me data which type is
IPaggedResults<Customer>
and I want to be able to map this to
IPaggedResults<CustomerDto>
It works if I invoke mapping with:
_mapper.Map<PaggedResults<CustomerDto>>
but I want use following syntax:
_mapper.Map<IPaggedResults<CustomerDto>>
public class PaggedResults<T> : IPaggedResults<T>
{
public IEnumerable<T> Results { get; protected set; }
public int TotalResults { get; protected set; }
public int TotalPages { get; protected set; }
public int ResultsPerPage { get; protected set; }
public PaggedResults(IEnumerable<T> results, int totalResults, int resultsPerPage)
{
Results = results;
TotalResults = totalResults;
TotalPages = totalResults / resultsPerPage;
ResultsPerPage = resultsPerPage;
}
}
public class CustomerDto
{
public int Id { get; set; }
public string Name { get; set; }
public string NIP { get; set; }
}
My mapper configuration:
public static IMapper Initialize()
=> new MapperConfiguration(cfg =>
{
cfg.CreateMap<CustomerCompany, CustomerDto>();
cfg.CreateMap(typeof(IPaggedResults<>), typeof(PaggedResults<>));
cfg.CreateMap(typeof(IPaggedResults<>), typeof(IPaggedResults<>)).As(typeof(PaggedResults<>));
}).CreateMapper();
Im'using Automapper by Jimmy Bogard.
I could achieve it through the following code:
Create an extension for IMapperConfigurationExpression
public static class IMapperConfigurationExpressionExtensions
{
public static void MapPaggedResults<TSource, TDestination>(this IMapperConfigurationExpression exp){
exp.CreateMap(typeof(PaggedResults<TSource>), typeof(IPaggedResults<TDestination>))
.ConstructUsing((source, ctx) => { return ctx.Mapper.Map<PaggedResults<TDestination>>(source) as IPaggedResults<TDestination>; });
}
}
Then use this configuration:
public static IMapper Initialize()
=> new MapperConfiguration(cfg =>
{
cfg.CreateMap(typeof(IPaggedResults<>), typeof(PaggedResults<>));
cfg.MapPaggedResults<CustomerCompany, CustomerDto>();
}).CreateMapper();
Then both results can be obtained:
var _mapper = Initialize();
IPaggedResults<CustomerCompany> source = new PaggedResults<CustomerCompany>(
new List<CustomerCompany>() { new CustomerCompany() {Id =42, Name = "SomeName", NIP = "someNIP" } }, 1, 1);
var resut = _mapper.Map<PaggedResults<CustomerDto>>(source);
var resut2 = _mapper.Map<IPaggedResults<CustomerDto>>(source);
I have list of my class type which I need to copy to another class type. In following code I am trying to copy GenderEntity to Gender but getting no results
private void MapGender()
{
List<GenderEntity> _GenderEntity = _GenderServiceObject.GenderEntity();
List<Gender> _Gender = new List<Gender>();
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<List<GenderEntity>, List<Gender>>();
});
IMapper mapper = config.CreateMapper();
_Gender = mapper.Map<List<GenderEntity>, List<Gender>>(_GenderEntity);
var x = "d";
}
GenderEntity - Source
public class GenderEntity
{
public GenderEntity() { }
public string Code { get; set; }
public string Description { get; set; }
}
Gender - Destination
[DataContract]
public class Gender
{
[DataMember]
public string Code { get; set; }
[DataMember]
public string Description { get; set; }
}
Gender entity is used for WCF SOAP services as data contract
Return List Class
public class GenderService
{
#region EBS Service return 'Gender'
public Gender GenderEBSEntity()
{
return GenderEBS.GetGender_EBS();
}
#endregion
#region Mapped Gender Entity
public List<GenderEntity> GenderEntity()
{
return GenderEBS.GetGenderEntity();
}
#endregion
}
You don't need to map Lists with AutoMapper, just create a map like:
cfg.CreateMap<GenderEntity, Gender>();
and then map it like this:
_Gender = mapper.Map<Gender[]>(_GenderEntity).ToList();
my answer...
private void MapGender()
{
List<Gender> MappedGender = new List<Contracts.Data.Gender>();
IList<GenderEntity> genderEntity = _GenderServiceObject.GenderEntity();
if(genderEntity!=null)
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<GenderEntity, Gender>();
});
IMapper mapper = config.CreateMapper();
gender = mapper.Map<IList<GenderEntity>, IList<Gender>>(genderEntity).ToList();
}
}
Is it possible to configure AutoMapper to set all properties to default value in case if the source object is null for specified classes? I know that I should use Mapper.AllowNullDestinationValues = false; to do what I want for all classes in application.
Here the sampled code that I use for tests, but it doesn't work
public class A
{
static A()
{
Mapper.Initialize(
config =>
{
config.ForSourceType<B>().AllowNullDestinationValues = false;
config.CreateMap<B, A>()
.ForMember(member => member.Name, opt => opt.Ignore());
});
//Mapper.AllowNullDestinationValues = false;
Mapper.AssertConfigurationIsValid();
}
public void Init(B b)
{
Mapper.DynamicMap(b, this);
}
public int? Foo { get; set; }
public double? Foo1 { get; set; }
public bool Foo2 { get; set; }
public string Name { get; set; }
}
public class B
{
public string Name { get; set; }
public int? Foo { get; set; }
public double? Foo1 { get; set; }
public bool Foo2 { get; set; }
}
Using of this code:
var b = new B() {Foo = 1, Foo1 = 3.3, Foo2 = true, Name = "123"};
var a = new A {Name = "aName"};
a.Init(b); // All ok: Name=aName, Foo=1, Foo1=3,3, Foo2=True
a.Init(null); // Should be Name=aName, Foo=null, Foo1=null, Foo2=False,
// but a has the same values as on a previous line
It must be related to "a" being already mapped.
var a = new A {Name = "aName"};
a.Init(b);
a.Init(null);
All mappings are cached, so if you'll attempt to re-map same instance the automapper would just keep the original result.
In order to test it, try:
var c = new A {Name = "x"};
c.Init(null);
Here is a link to similar question.
Looks like it will replace with null if you set Mapper.Configuration.AllowNullDestinationValues = false:
public class A
{
static A()
{
Mapper.Initialize(
config =>
{
config.ForSourceType<B>().AllowNullDestinationValues = false;
config.CreateMap<B, A>()
.ForMember(member => member.Name, opt => opt.Ignore());
});
Mapper.Configuration.AllowNullDestinationValues = false;
Mapper.AssertConfigurationIsValid();
}
public void Init(B b)
{
Mapper.DynamicMap(b, this);
}
public int? Foo { get; set; }
public double? Foo1 { get; set; }
public bool Foo2 { get; set; }
public string Name { get; set; }
}