如何修复未映射的成员?

时间:2018-12-27 10:29:38

标签: asp.net .net asp.net-core automapper asp.net-core-mvc-2.1

我正在建立一个新项目,以浏览电影并给出您的意见。现在,我在管理部分,并添加了添加影片的功能,但是当我尝试添加影片时,自动映射器会在将dto映射到数据模型的服务上引发未映射成员的异常。成员来自基础数据模型,例如id。

编辑

我试图忽略所有导致此异常的成员,还试图使构造函数不带参数但不起作用。

// Initialization
Mapper.Initialize(conf =>
        {
            conf.CreateMap<Movie, MovieDto>();
            conf.CreateMap<MovieDto, Movie>();
            conf.CreateMap<MovieDto, MovieViewModel>();
        });

// Base Data Model
public class DataModel
{
    [Key]
    public int Id { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime? CreatedOn { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime? ModifiedOn { get; set; }

    public bool IsDeleted { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime? DeletedOn { get; set; }
}

// Movie Data Model
public class Movie: DataModel
{

    public Movie(string title, double rating, string duration, string type, string description, DateTime releaseDate, string producer)
    {
        this.Title = title;
        this.Rating = rating;
        this.Duration = duration;
        this.Type = type;
        this.Description = description;
        this.ReleaseDate = releaseDate;
        this.Producer = producer;
    }

    // successfully mapped members
}

// Movie DTO
public class MovieDto
{
    public string Title { get; set; }

    public double Rating { get; set; }

    public string Duration { get; set; }

    public string Type { get; set; }

    public string Description { get; set; }

    public DateTime ReleaseDate { get; set; }

    public string Producer { get; set; }
}

 // Add functionality 
 public void AddMovie(MovieDto movie)
 {
      //execption here
      var movieDM = this.mapper.Map<Movie>(movie);

      this.repo.Add(movieDM);

      this.saver.SaveChanges();
 }

这是img上的例外:https://i.imgur.com/RGZP6NP.png

3 个答案:

答案 0 :(得分:1)

通过执行以下操作使其起作用。 首先,由于DataModel是基类,因此我遵循了自动映射器的映射继承(see docs)。 然后,由于您使用的是映射器实例来映射this.mapper.Map<Movie>(movie),因此配置也必须是实例而不是静态的,为此我使用了AutoMapper.Extensions.Microsoft.DependencyInjection nuget包,该包允许向IoC容器注册Automapper

我的配置如下所示(在Startup类的ConfigureServices方法内部)。

            services.AddAutoMapper(conf =>
        {
            conf.CreateMap<object, DataModel>()
                .ForMember(d => d.Id, opts => opts.Ignore())
                .ForMember(d => d.CreatedOn, opts => opts.MapFrom(_ => DateTime.Now))
                .ForMember(d => d.ModifiedOn, opts => opts.MapFrom(_ => DateTime.Now))
                .ForMember(d => d.DeletedOn, opts => opts.MapFrom(_ => (DateTime?)null))
                .ForMember(d => d.IsDeleted, opts => opts.MapFrom(_ => false))
                .Include<MovieDto, Movie>();
            conf.CreateMap<Movie, MovieDto>();
            conf.CreateMap<MovieDto, Movie>();
        });

请注意,我在基类映射中使用了CreateMap<object, DataModel>,而在那里只对日期使用了硬编码值,请随时进行调整以适应您的情况。

注入IMapper的实例后,我能够成功调用this.mapper.Map<Movie>(movie)

希望这会使您朝着正确的方向前进。

答案 1 :(得分:0)

您可以指定AutoMapper不应验证是否已映射所有属性。创建映射配置时,可以使用MemberList枚举。例如:

conf.CreateMap<MovieDto, Movie>(MemberList.None)

但是,屏幕截图中的错误表明存在另一映射问题,即从MovieViewModelMovieDto的映射。我建议您也为这些类型添加一个映射配置:

conf.CreateMap<MovieViewModel, MovieDto>(MemberList.None)

答案 2 :(得分:0)

您可以尝试Profile Instances

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<OrderViewModel, Order>()
            .ForMember(dest => dest.OrderItem, opt => opt.MapFrom(src => src.OrderItemViewModel));
        CreateMap<OrderItemViewModel, OrderItem>();
        CreateMap<Order, Order>()
            .ForMember(dest => dest.Id, opt => opt.Ignore());

        CreateMap<Movie, MovieDto>();
        CreateMap<MovieDto, Movie>();
    }
}

这是工作示例AutoMapperProfile