user1798599 user1798599 - 16 days ago 22
C# Question

Mapper.Map<Task<IEnumerable<Address>>, Task<IEnumerable<AddressView>>()

.NET Framework 4.5.2, .Asp.NET Web API 5.2.3, AutoMapper 5.1.1

I have the following ASP.NET MVC WebApi Action Method on the AddressController. For my test I return only 10 records as you can see in service method below:

[Route("api/Address/GetAllAsync")]
[HttpGet]
public async Task<IEnumerable<AddressModel>> GetAllAsync()
{
AddressService service = new AddressService(new DataContext());
Task<IEnumerable<Address>> data = service.GetAllAddressesAsync();
var addressList = Mapper.Map<Task<IEnumerable<Address>>, Task<IEnumerable<AddressModel>>>(data);

return await addressList;
}


service.GetAllAddressesAsync is

public async Task<IEnumerable<Address>> GetAlladdressesAsync()
{
var data = from a in _context.Addresses.Take(10)
orderby a.City
select a;

return await data.ToListAsync();
}


AutoMapper is configured in Global.asax.cs as:

Mapper.Initialize(cfg => cfg.CreateMap<Address, AddressModel>());
Mapper.AssertConfigurationIsValid();


I have also tried to configure AutoMapper like

Mapper.Initialize(cfg => cfg.CreateMap<Task<IEnumerable<Address>>, Task<IEnumerable<AddressModel>>>());
Mapper.AssertConfigurationIsValid();


With the first configuration the solution starts but when calling the GetAllAsync() method from browser the Response body (in F12 Developer Tools / Networking) shows the following error message:

{"message":"An error has occurred.","exceptionMessage":"Missing type map configuration or unsupported mapping.\r\n\r\nMapping types:\r\nTask
1 -> Task
1\r\nSystem.Threading.Tasks.Task
1[[System.Collections.Generic.IEnumerable
1[[DataAccess.Address, DataAccess, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] -> System.Threading.Tasks.Task
1[[System.Collections.Generic.IEnumerable
1[[TestAspNetIdentity.Models.AddressModel, TestAspNetIdentity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]","exceptionType":"AutoMapper.AutoMapperMappingException","stackTrace":"

When trying the second configuration of AutoMapper the solution starts but when calling the method the request dies without any Response or exception on client or on server and the browser waits on Response in a indefinite Loop.

How should I configure and use AutoMapper to map
Task<IEnumerable<MyTypeA>>
to
Task<IEnumerable<MyTypeB>>
? Do I make some basic Errors with async-task-awayt usage? Does anybody have an example?
Thank you for your help.

Regards
Adrian

Answer

You should not be trying to map a Task - await the result of the task and map that:

[Route("api/Address/GetAllAsync")]
[HttpGet]
public async Task<IEnumerable<AddressModel>> GetAllAsync()
{
    AddressService service = new AddressService(new DataContext());
    IEnumerable<Address> data = await service.GetAllAddressesAsync();
    var addressList = Mapper.Map<IEnumerable<AddressModel>>(data);

    return addressList;
}

Also, you don't need to specify the source type when mapping.