I have an application I haven't touched for a while and it is giving me some grief.
When I call the index method of the controller I get the following error:
I am not sure what I am doing wrong but it would seem that AutoMapper is having trouble mapping a collection of Shift objects to a ShiftViewModel.
I have included some snippets below.
Thoughts?
My controller:
using AutoMapper;
using My.DataAccess;
using My.Entity.DatabaseEntities;
using My.Entity.ViewModels;
using My.Service;
using System.Net;
using System.Threading.Tasks;
using System.Web.Mvc;
namespace My.Controllers
{
public class ShiftController : Controller
{
//initialize service object
readonly IShiftService _shiftService;
private readonly IMapper _mapper;
public ShiftController(IShiftService shiftService, IMapper mapper)
{
_shiftService = shiftService;
_mapper = mapper;
}
readonly ApplicationDataManager db = new ApplicationDataManager();
// GET: /Shifts/
public ActionResult Index()
{
var shifts = _shiftService.GetAll();
if (shifts == null)
{
return HttpNotFound();
}
var model = _mapper.Map<ShiftViewModel>(shifts);
return View(model);
}
}
}
Shift database entity:
using System;
using System.ComponentModel.DataAnnotations;
namespace My.Entity.DatabaseEntities
{
public class Shift : AuditableEntity<long>
{
[Required, StringLength(6)]
[Editable(true)]
public string Code { get; set; }
public string Detail { get; set; }
public DateTime Start { get; set; }
public long Duration { get; set; }
}
}
ShiftViewModel class:
using System;
using System.ComponentModel.DataAnnotations;
namespace My.Entity.ViewModels
{
public class ShiftViewModel
{
public int Id { get; set; }
public string Code { get; set; }
public string Detail { get; set; }
public DateTime Start { get; set; }
[Display(Name = "Duration of shift")]
[DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
[DataType(DataType.Duration)]
public string DurationTime
{
get
{
var ts = new TimeSpan(Duration);
var h = ts.Hours == 1 ? "hour" : "hours";
var m = ts.Minutes == 1 ? "min" : "mins";
return string.Format("{0} {1} {2} {3}", ts.Hours, h, ts.Minutes, m);
}
}
public long Duration { get; set; }
}
}
Global.asax:
using Autofac;
using Autofac.Integration.Mvc;
using My.DataAccess.Modules;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace My.App
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//Autofac Configuration
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
builder.RegisterModule(new RepositoryModule());
builder.RegisterModule(new ServiceModule());
builder.RegisterModule(new EFModule());
//Register AutoMapper here using AutoFacModule class (Both methods works)
//builder.RegisterModule(new AutoMapperModule());
builder.RegisterModule<AutoFacModule>();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
}
AutoFacModule:
using Autofac;
using AutoFacAndAutoMapperMVC.Infrastructure;
using AutoMapper;
public class AutoFacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register(context => new MapperConfiguration(cfg =>
{
//Register Mapper Profile
cfg.AddProfile<AutoMapperProfile>();
}
)).AsSelf().InstancePerRequest();
builder.Register(c =>
{
//This resolves a new context that can be used later.
var context = c.Resolve<IComponentContext>();
var config = context.Resolve<MapperConfiguration>();
return config.CreateMapper(context.Resolve);
})
.As<IMapper>()
.InstancePerLifetimeScope();
}
}
AutoMapperProfile:
using Roster.Entity.DatabaseEntities;
using Roster.Entity.ViewModels;
using AutoMapper;
namespace AutoFacAndAutoMapperMVC.Infrastructure
{
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<Shift, ShiftViewModel>();
CreateMap<ShiftViewModel, Shift>();
}
}
}
Trekco, It is called by a generic method of IEnumerable
public virtual IEnumerable<T> GetAll()
{
return _repository.GetAll();
}
it returns a Shift object

_shiftService.GetAll()return. Automapper will also tell you what mapping is missing in the exception.