如何使用 AutoMapper 从 DTO 到 Model both PUT/POST 进行映射?

How to do mapping using AutoMapper from DTO to Model both PUT/POST?

我已经按照从模型到 DTO 的方式完成了 AutoMapper,并且效果很好。

private ApplicationDbContext db = new ApplicationDbContext();

        private MapperConfiguration configuration = new MapperConfiguration(cfg =>
                                        cfg.CreateMap<Activity, ActivityDTO>()
                                            .ForMember(dto => dto.OwnerName, conf => conf.MapFrom(ol => ol.User.FirstName + " " + ol.User.LastName))
                                            .ForMember(dto => dto.CategoryName, conf => conf.MapFrom(ol => ol.Category.Name)));

// GET: api/v1/Activities/5
        [HttpGet]
        [ResponseType(typeof(ActivityDTO))]
        [Route("api/v1/Activities/{id}", Name = "GetActivity")]
        public async Task<IHttpActionResult> GetActivity(int id)
        {
            string userId = User.Identity.GetUserId();

            var activityDTO = await db.Activities
                                        .Include(b => b.User)
                                        .Include(c => c.Category)
                                        .Where(q => q.UserId == userId && q.Id == id)
                                        //.Select(AsActivityDto)
                                        .ProjectTo<ActivityDTO>(configuration)
                                        .FirstOrDefaultAsync();

            if (activityDTO == null)
            {
                return NotFound();
            }

            return Ok(activityDTO);
        }

然后我不确定如何在为 Put/Post 控制器保存数据之前将此 AutoMapper 从 DTO 返回到模型。处理这个:

activity.CategoryId = category.Id; activity.Name = activityDTO.Name; activity.Description = activityDTO.Description; activity.NoOfMinutes = activityDTO.NoOfMinutes; activity.DateModified = DateTime.UtcNow;

var activity = 新 Activity { UserId = 用户Id, CategoryId = category.Id, 名字=activityDTO.Name, 说明 = activityDTO.Description, NoOfMinutes = activityDTO.NoOfMinutes, 创建日期 = DateTime.UtcNow, 修改日期 = DateTime.UtcNow };

// PUT: api/v1/Activities/5
        [HttpPut]
        [Route("api/v1/Activities/{id}")]
        [ResponseType(typeof(void))]
        public async Task<IHttpActionResult> PutActivity(int id, ActivityDTO activityDTO)
        {
            string userId = User.Identity.GetUserId();

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);

            if (category == null)
            {
                return BadRequest("Category not valid.");
            }

            if (id != activityDTO.Id)
            {
                return BadRequest();
            }

            var activity = await db.Activities.FirstOrDefaultAsync(q => q.Id == id);

            if (activity == null)
            {
                return NotFound();
            }

            if (userId != activity.UserId)
            {
                return BadRequest("No right access to update");
            }

            activity.CategoryId = category.Id;
            activity.Name = activityDTO.Name;
            activity.Description = activityDTO.Description;
            activity.NoOfMinutes = activityDTO.NoOfMinutes;
            activity.DateModified = DateTime.UtcNow;

            db.Entry(activity).State = EntityState.Modified;

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ActivityExists(id))
                {
                    return NotFound();
                }
                else
                {
                    return BadRequest("The model is invalid");
                }
            }

            return Ok();
        }

        // POST: api/Activities
        [HttpPost]
        [Route("api/v1/Activities")]
        [ResponseType(typeof(Activity))]
        public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
        {
            string userId = User.Identity.GetUserId();

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);

            if (category == null)
            {
                return BadRequest("Category not valid.");
            }

            var activity = new Activity
            {
                UserId = userId,
                CategoryId = category.Id,
                Name = activityDTO.Name,
                Description = activityDTO.Description,
                NoOfMinutes = activityDTO.NoOfMinutes,
                DateCreated = DateTime.UtcNow,
                DateModified = DateTime.UtcNow
            };

            db.Activities.Add(activity);

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                return BadRequest("The model is invalid");
            }

            var newActivityDto = await db.Activities
                                        .Include(b => b.User)
                                        .Include(c => c.Category)
                                        .Where(q => q.UserId == userId && q.Id == activity.Id)
                                        //.Select(AsActivityDto)
                                        .ProjectTo<ActivityDTO>(configuration)
                                        .FirstOrDefaultAsync();

            return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
        }

更新:

private MapperConfiguration configuration = new MapperConfiguration(cfg => {
                                                                                cfg.CreateMap<Activity, ActivityDTO>()
                                                                                    .ForMember(dst => dst.OwnerName, src => src.MapFrom(ol => ol.User.FirstName + " " + ol.User.LastName))
                                                                                    .ForMember(dst => dst.CategoryName, src => src.MapFrom(ol => ol.Category.Name));
            cfg.CreateMap<ActivityDTO, Activity>()
                .ForMember(dst => dst.UserId, opt => opt.MapFrom(src => HttpContext.Current.User.Identity.GetUserId()))
                .ForMember(dst => dst.CategoryId, opt => opt.MapFrom(src => GetCategoryId(HttpContext.Current.User.Identity.GetUserId(), src.CategoryName)))
                .ForMember(dst => dst.DateCreated, opt => opt.MapFrom(src => DateTime.UtcNow))
                .ForMember(dst => dst.DateModified, opt => opt.MapFrom(src => DateTime.UtcNow));
        });

修改POST如下:

 // POST: api/Activities
        [HttpPost]
        [Route("api/v1/Activities")]
        [ResponseType(typeof(Activity))]
        public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
        {
            string userId = User.Identity.GetUserId();

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);

            if (category == null)
            {
                return BadRequest("Category not valid.");
            }

            /*category.UserId = userId,
                CategoryId = category.Id,
                Name = activityDTO.Name,
                Description = activityDTO.Description,
                NoOfMinutes = activityDTO.NoOfMinutes,
                DateCreated = DateTime.UtcNow,
                DateModified = DateTime.UtcNow
            };*/

            //var activity = mapper.Map<ActivityDTO, Activity>(activityDTO);
            var activity = configuration.CreateMapper().Map<ActivityDTO, Activity>(activityDTO);


            db.Activities.Add(activity);

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                return BadRequest("The model is invalid");
            }

            var newActivityDto = await db.Activities
                                        .Include(b => b.User)
                                        .Include(c => c.Category)
                                        .Where(q => q.UserId == userId && q.Id == activity.Id)
                                        //.Select(AsActivityDto)
                                        .ProjectTo<ActivityDTO>(configuration)
                                        .FirstOrDefaultAsync();

            return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
        }

您需要在 MapperConfiguration

中映射您的 add/update DTO
CreateMap<ActivityDTO, Activity>();
CreateMap<ActivityUpdateDTO, Activity>();

然后需要添加mapper

public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
        {
            string userId = User.Identity.GetUserId();

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);

            if (category == null)
            {
                return BadRequest("Category not valid.");
            }

            //var activity = new Activity
            //{
                //UserId = userId,
                //CategoryId = category.Id,
                //Name = activityDTO.Name,
                //Description = activityDTO.Description,
                //NoOfMinutes = activityDTO.NoOfMinutes,
                //DateCreated = DateTime.UtcNow,
                //DateModified = DateTime.UtcNow
            //};

            var activity = Mapper.Map<ActivityDTO, Activity>(activityDTO);

            db.Activities.Add(activity);

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                return BadRequest("The model is invalid");
            }

            var newActivityDto = await db.Activities
                                        .Include(b => b.User)
                                        .Include(c => c.Category)
                                        .Where(q => q.UserId == userId && q.Id == activity.Id)
                                        //.Select(AsActivityDto)
                                        .ProjectTo<ActivityDTO>(configuration)
                                        .FirstOrDefaultAsync();

            return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
        }

去掉这两行

.ForMember(dst => dst.DateCreated, opt => opt.MapFrom(src => DateTime.UtcNow))
.ForMember(dst => dst.DateModified, opt => opt.MapFrom(src => DateTime.UtcNow));

像这样添加你的 DTO

    public class ActivityDTO
    {
        public ActivityDTO()
        {
            DateCreated = DateTime.UtcNow;
        }
        public DateTime DateCreated { get; set; }

        // other properties
    }
    public class ActivityUpdateDTO
    {
        public ActivityUpdateDTO()
        {
            DateModified = DateTime.UtcNow;
        }
        public DateTime DateModified { get; set; }

        // other properties
    }